thomascube
2006-05-01 6204390af16bcf50f82da61a1aefc2ad0c0adf94
commit | author | age
b076a4 1 <?php
T 2 // vim: set et ts=4 sw=4 fdm=marker:
3 // +----------------------------------------------------------------------+
4 // | PHP versions 4 and 5                                                 |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
7 // | Stig. S. Bakken, Lukas Smith                                         |
8 // | All rights reserved.                                                 |
9 // +----------------------------------------------------------------------+
10 // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
11 // | API as well as database abstraction for PHP applications.            |
12 // | This LICENSE is in the BSD license style.                            |
13 // |                                                                      |
14 // | Redistribution and use in source and binary forms, with or without   |
15 // | modification, are permitted provided that the following conditions   |
16 // | are met:                                                             |
17 // |                                                                      |
18 // | Redistributions of source code must retain the above copyright       |
19 // | notice, this list of conditions and the following disclaimer.        |
20 // |                                                                      |
21 // | Redistributions in binary form must reproduce the above copyright    |
22 // | notice, this list of conditions and the following disclaimer in the  |
23 // | documentation and/or other materials provided with the distribution. |
24 // |                                                                      |
25 // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
26 // | Lukas Smith nor the names of his contributors may be used to endorse |
27 // | or promote products derived from this software without specific prior|
28 // | written permission.                                                  |
29 // |                                                                      |
30 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
31 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
32 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
33 // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
34 // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
35 // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
36 // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
37 // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
38 // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
39 // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
40 // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
41 // | POSSIBILITY OF SUCH DAMAGE.                                          |
42 // +----------------------------------------------------------------------+
43 // | Author: Lukas Smith <smith@pooteeweet.org>                           |
44 // +----------------------------------------------------------------------+
45 //
46 // $Id$
47 //
48
49 require_once 'MDB2/Driver/Datatype/Common.php';
50
51 /**
52  * MDB2 MySQL driver
53  *
54  * @package MDB2
55  * @category Database
56  * @author  Lukas Smith <smith@pooteeweet.org>
57  */
58 class MDB2_Driver_Datatype_mysql extends MDB2_Driver_Datatype_Common
59 {
60     // }}}
61     // {{{ _getIntegerDeclaration()
62
63     /**
64      * Obtain DBMS specific SQL code portion needed to declare an integer type
65      * field to be used in statements like CREATE TABLE.
66      *
67      * @param string  $name   name the field to be declared.
68      * @param string  $field  associative array with the name of the properties
69      *                        of the field being declared as array indexes.
70      *                        Currently, the types of supported field
71      *                        properties are as follows:
72      *
73      *                       unsigned
74      *                        Boolean flag that indicates whether the field
75      *                        should be declared as unsigned integer if
76      *                        possible.
77      *
78      *                       default
79      *                        Integer value to be used as default for this
80      *                        field.
81      *
82      *                       notnull
83      *                        Boolean flag that indicates whether this field is
84      *                        constrained to not be set to null.
85      * @return string  DBMS specific SQL code portion that should be used to
86      *                 declare the specified field.
87      * @access protected
88      */
89     function _getIntegerDeclaration($name, $field)
90     {
91         if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
92             $autoinc = ' AUTO_INCREMENT PRIMARY KEY';
93             $default = '';
94         } else {
95             $autoinc = '';
96             $default = array_key_exists('default', $field) ? ' DEFAULT '.
97                 $this->quote($field['default'], 'integer') : '';
98         }
99
100         $unsigned = (array_key_exists('unsigned', $field) && $field['unsigned']) ? ' UNSIGNED' : '';
101         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
102         return $name.' INT'.$unsigned.$default.$notnull.$autoinc;
103     }
104
105     // }}}
106     // {{{ _getCLOBDeclaration()
107
108     /**
109      * Obtain DBMS specific SQL code portion needed to declare an character
110      * large object type field to be used in statements like CREATE TABLE.
111      *
112      * @param string  $name   name the field to be declared.
113      * @param string  $field  associative array with the name of the
114      *                        properties of the field being declared as array
115      *                        indexes. Currently, the types of supported field
116      *                        properties are as follows:
117      *
118      *                       length
119      *                        Integer value that determines the maximum length
120      *                        of the large object field. If this argument is
121      *                        missing the field should be declared to have the
122      *                        longest length allowed by the DBMS.
123      *
124      *                       notnull
125      *                        Boolean flag that indicates whether this field
126      *                        is constrained to not be set to null.
127      * @return string  DBMS specific SQL code portion that should be used to
128      *                 declare the specified field.
129      * @access protected
130      */
131     function _getCLOBDeclaration($name, $field)
132     {
133         if (array_key_exists('length', $field)) {
134             $length = $field['length'];
135             if ($length <= 255) {
136                 $type = 'TINYTEXT';
137             } else {
138                 if ($length <= 65535) {
139                     $type = 'TEXT';
140                 } else {
141                     if ($length <= 16777215) {
142                         $type = 'MEDIUMTEXT';
143                     } else {
144                         $type = 'LONGTEXT';
145                     }
146                 }
147             }
148         } else {
149             $type = 'LONGTEXT';
150         }
151         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
152         return $name.' '.$type.$notnull;
153     }
154
155     // }}}
156     // {{{ _getBLOBDeclaration()
157
158     /**
159      * Obtain DBMS specific SQL code portion needed to declare an binary large
160      * object type field to be used in statements like CREATE TABLE.
161      *
162      * @param string  $name   name the field to be declared.
163      * @param string  $field  associative array with the name of the properties
164      *                        of the field being declared as array indexes.
165      *                        Currently, the types of supported field
166      *                        properties are as follows:
167      *
168      *                       length
169      *                        Integer value that determines the maximum length
170      *                        of the large object field. If this argument is
171      *                        missing the field should be declared to have the
172      *                        longest length allowed by the DBMS.
173      *
174      *                       notnull
175      *                        Boolean flag that indicates whether this field is
176      *                        constrained to not be set to null.
177      * @return string  DBMS specific SQL code portion that should be used to
178      *                 declare the specified field.
179      * @access protected
180      */
181     function _getBLOBDeclaration($name, $field)
182     {
183         if (array_key_exists('length', $field)) {
184             $length = $field['length'];
185             if ($length <= 255) {
186                 $type = 'TINYBLOB';
187             } else {
188                 if ($length <= 65535) {
189                     $type = 'BLOB';
190                 } else {
191                     if ($length <= 16777215) {
192                         $type = 'MEDIUMBLOB';
193                     } else {
194                         $type = 'LONGBLOB';
195                     }
196                 }
197             }
198         } else {
199             $type = 'LONGBLOB';
200         }
201         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
202         return $name.' '.$type.$notnull;
203     }
204
205     // }}}
206     // {{{ _getDateDeclaration()
207
208     /**
209      * Obtain DBMS specific SQL code portion needed to declare an date type
210      * field to be used in statements like CREATE TABLE.
211      *
212      * @param string  $name   name the field to be declared.
213      * @param string  $field  associative array with the name of the properties
214      *                        of the field being declared as array indexes.
215      *                        Currently, the types of supported field properties
216      *                        are as follows:
217      *
218      *                       default
219      *                        Date value to be used as default for this field.
220      *
221      *                       notnull
222      *                        Boolean flag that indicates whether this field is
223      *                        constrained to not be set to null.
224      * @return string  DBMS specific SQL code portion that should be used to
225      *                 declare the specified field.
226      * @access protected
227      */
228     function _getDateDeclaration($name, $field)
229     {
230         $default = array_key_exists('default', $field) ? ' DEFAULT '.
231             $this->quote($field['default'], 'date') : '';
232         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
233         return $name.' DATE'.$default.$notnull;
234     }
235
236     // }}}
237     // {{{ _getTimestampDeclaration()
238
239     /**
240      * Obtain DBMS specific SQL code portion needed to declare an timestamp
241      * type field to be used in statements like CREATE TABLE.
242      *
243      * @param string  $name   name the field to be declared.
244      * @param string  $field  associative array with the name of the properties
245      *                        of the field being declared as array indexes.
246      *                        Currently, the types of supported field
247      *                        properties are as follows:
248      *
249      *                       default
250      *                        Time stamp value to be used as default for this
251      *                        field.
252      *
253      *                       notnull
254      *                        Boolean flag that indicates whether this field is
255      *                        constrained to not be set to null.
256      * @return string  DBMS specific SQL code portion that should be used to
257      *                 declare the specified field.
258      * @access protected
259      */
260     function _getTimestampDeclaration($name, $field)
261     {
262         $default = array_key_exists('default', $field) ? ' DEFAULT '.
263             $this->quote($field['default'], 'timestamp') : '';
264         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
265         return $name.' DATETIME'.$default.$notnull;
266     }
267
268     // }}}
269     // {{{ _getTimeDeclaration()
270
271     /**
272      * Obtain DBMS specific SQL code portion needed to declare an time type
273      * field to be used in statements like CREATE TABLE.
274      *
275      * @param string  $name   name the field to be declared.
276      * @param string  $field  associative array with the name of the properties
277      *                        of the field being declared as array indexes.
278      *                        Currently, the types of supported field
279      *                        properties are as follows:
280      *
281      *                       default
282      *                        Time value to be used as default for this field.
283      *
284      *                       notnull
285      *                        Boolean flag that indicates whether this field is
286      *                        constrained to not be set to null.
287      * @return string  DBMS specific SQL code portion that should be used to
288      *                 declare the specified field.
289      * @access protected
290      */
291     function _getTimeDeclaration($name, $field)
292     {
293         $default = array_key_exists('default', $field) ? ' DEFAULT '.
294             $this->quote($field['default'], 'time') : '';
295         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
296         return $name.' TIME'.$default.$notnull;
297     }
298
299     // }}}
300     // {{{ _getFloatDeclaration()
301
302     /**
303      * Obtain DBMS specific SQL code portion needed to declare an float type
304      * field to be used in statements like CREATE TABLE.
305      *
306      * @param string  $name   name the field to be declared.
307      * @param string  $field  associative array with the name of the properties
308      *                        of the field being declared as array indexes.
309      *                        Currently, the types of supported field
310      *                        properties are as follows:
311      *
312      *                       default
313      *                        Integer value to be used as default for this
314      *                        field.
315      *
316      *                       notnull
317      *                        Boolean flag that indicates whether this field is
318      *                        constrained to not be set to null.
319      * @return string  DBMS specific SQL code portion that should be used to
320      *                 declare the specified field.
321      * @access protected
322      */
323     function _getFloatDeclaration($name, $field)
324     {
325         $type = 'DOUBLE';
326         $default = array_key_exists('default', $field) ? ' DEFAULT '.
327             $this->quote($field['default'], 'float') : '';
328         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
329         return $name.' '.$type.$default.$notnull;
330     }
331
332     // }}}
333     // {{{ _getDecimalDeclaration()
334
335     /**
336      * Obtain DBMS specific SQL code portion needed to declare an decimal type
337      * field to be used in statements like CREATE TABLE.
338      *
339      * @param string  $name   name the field to be declared.
340      * @param string  $field  associative array with the name of the properties
341      *                        of the field being declared as array indexes.
342      *                        Currently, the types of supported field
343      *                        properties are as follows:
344      *
345      *                       default
346      *                        Integer value to be used as default for this
347      *                        field.
348      *
349      *                       notnull
350      *                        Boolean flag that indicates whether this field is
351      *                        constrained to not be set to null.
352      * @return string  DBMS specific SQL code portion that should be used to
353      *                 declare the specified field.
354      * @access protected
355      */
356     function _getDecimalDeclaration($name, $field)
357     {
358         $db =& $this->getDBInstance();
359         if (PEAR::isError($db)) {
360             return $db;
361         }
362
363         $type = 'DECIMAL(18,'.$db->options['decimal_places'].')';
364         $default = array_key_exists('default', $field) ? ' DEFAULT '.
365             $this->quote($field['default'], 'decimal') : '';
366         $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
367         return $name.' '.$type.$default.$notnull;
368     }
369
370     // }}}
371     // {{{ _quoteBLOB()
372
373     /**
374      * Convert a text value into a DBMS specific format that is suitable to
375      * compose query statements.
376      *
377      * @param           $value
378      * @return string  text string that represents the given argument value in
379      *                 a DBMS specific format.
380      * @access protected
381      */
382     function _quoteBLOB($value)
383     {
384         $value = $this->_readFile($value);
385         return "'".addslashes($value)."'";
386     }
387
388     // }}}
389     // {{{ _quoteFloat()
390
391     /**
392      * Convert a text value into a DBMS specific format that is suitable to
393      * compose query statements.
394      *
395      * @param string  $value text string value that is intended to be converted.
396      * @return string  text string that represents the given argument value in
397      *                 a DBMS specific format.
398      * @access protected
399      */
400     function _quoteFloat($value)
401     {
402         return (float)$value;
403     }
404
405     // }}}
406     // {{{ _quoteDecimal()
407
408     /**
409      * Convert a text value into a DBMS specific format that is suitable to
410      * compose query statements.
411      *
412      * @param string  $value text string value that is intended to be converted.
413      * @return string  text string that represents the given argument value in
414      *                 a DBMS specific format.
415      * @access protected
416      */
417     function _quoteDecimal($value)
418     {
419         $db =& $this->getDBInstance();
420         if (PEAR::isError($db)) {
421             return $db;
422         }
423
424         return $db->escape($value);
425     }
426
427     // }}}
428     // {{{ mapNativeDatatype()
429
430     /**
431      * Maps a native array description of a field to a MDB2 datatype and length
432      *
433      * @param array  $field native field description
434      * @return array containing the various possible types and the length
435      * @access public
436      */
437     function mapNativeDatatype($field)
438     {
439         $db_type = strtolower($field['type']);
440         $db_type = strtok($db_type, '(), ');
441         if ($db_type == 'national') {
442             $db_type = strtok('(), ');
443         }
444         $length = strtok('(), ');
445         $decimal = strtok('(), ');
446         $type = array();
447         switch ($db_type) {
448         case 'tinyint':
449         case 'smallint':
450         case 'mediumint':
451         case 'int':
452         case 'integer':
453         case 'bigint':
454             $type[] = 'integer';
455             if ($length == '1') {
456                 $type[] = 'boolean';
457                 if (preg_match('/^[is|has]/', $field['field'])) {
458                     $type = array_reverse($type);
459                 }
460             }
461             break;
462         case 'char':
463         case 'varchar':
464             $type[] = 'text';
465             if ($length == '1') {
466                 $type[] = 'boolean';
467                 if (preg_match('/[is|has]/', $field['field'])) {
468                     $type = array_reverse($type);
469                 }
470             }
471             break;
472         case 'enum':
473             preg_match_all('/\'.+\'/U', $field['type'], $matches);
474             $length = 0;
475             if (is_array($matches)) {
476                 foreach ($matches[0] as $value) {
477                     $length = max($length, strlen($value)-2);
478                 }
479             }
480         case 'set':
481             $type[] = 'text';
482             $type[] = 'integer';
483             break;
484         case 'date':
485             $type[] = 'date';
486             $length = null;
487             break;
488         case 'datetime':
489         case 'timestamp':
490             $type[] = 'timestamp';
491             $length = null;
492             break;
493         case 'time':
494             $type[] = 'time';
495             $length = null;
496             break;
497         case 'float':
498         case 'double':
499         case 'real':
500             $type[] = 'float';
501             break;
502         case 'decimal':
503         case 'numeric':
504             $type[] = 'decimal';
505             break;
506         case 'tinytext':
507         case 'mediumtext':
508         case 'longtext':
509         case 'text':
510             if ($decimal == 'binary') {
511                 $type[] = 'blob';
512             }
513             $type[] = 'clob';
514             $type[] = 'text';
515             break;
516         case 'tinyblob':
517         case 'mediumblob':
518         case 'longblob':
519         case 'blob':
520             $type[] = 'blob';
521             $type[] = 'text';
522             $length = null;
523             break;
524         case 'year':
525             $type[] = 'integer';
526             $type[] = 'date';
527             $length = null;
528             break;
529         default:
530             $db =& $this->getDBInstance();
531             if (PEAR::isError($db)) {
532                 return $db;
533             }
534
535             return $db->raiseError(MDB2_ERROR, null, null,
536                 'getTableFieldDefinition: unknown database attribute type');
537         }
538
539         return array($type, $length);
540     }
541 }
542
543 ?>