thomascube
2006-03-04 f5121b5639992fc9e51fd551bac2254429b638fa
commit | author | age
b076a4 1 <?php
T 2 // +----------------------------------------------------------------------+
3 // | PHP versions 4 and 5                                                 |
4 // +----------------------------------------------------------------------+
5 // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
6 // | Stig. S. Bakken, Lukas Smith                                         |
7 // | All rights reserved.                                                 |
8 // +----------------------------------------------------------------------+
9 // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
10 // | API as well as database abstraction for PHP applications.            |
11 // | This LICENSE is in the BSD license style.                            |
12 // |                                                                      |
13 // | Redistribution and use in source and binary forms, with or without   |
14 // | modification, are permitted provided that the following conditions   |
15 // | are met:                                                             |
16 // |                                                                      |
17 // | Redistributions of source code must retain the above copyright       |
18 // | notice, this list of conditions and the following disclaimer.        |
19 // |                                                                      |
20 // | Redistributions in binary form must reproduce the above copyright    |
21 // | notice, this list of conditions and the following disclaimer in the  |
22 // | documentation and/or other materials provided with the distribution. |
23 // |                                                                      |
24 // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
25 // | Lukas Smith nor the names of his contributors may be used to endorse |
26 // | or promote products derived from this software without specific prior|
27 // | written permission.                                                  |
28 // |                                                                      |
29 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
30 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
31 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
32 // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
33 // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
34 // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
35 // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
36 // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
37 // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
38 // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
39 // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
40 // | POSSIBILITY OF SUCH DAMAGE.                                          |
41 // +----------------------------------------------------------------------+
42 // | Author: Lukas Smith <smith@pooteeweet.org>                           |
43 // +----------------------------------------------------------------------+
44 //
45 // $Id$
46 //
47
48 require_once 'MDB2/Driver/Reverse/Common.php';
49
50 /**
51  * MDB2 MySQL driver for the schema reverse engineering module
52  *
53  * @package MDB2
54  * @category Database
55  * @author  Lukas Smith <smith@pooteeweet.org>
56  */
57 class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
58 {
59     // {{{ getTableFieldDefinition()
60
61     /**
62      * get the stucture of a field into an array
63      *
64      * @param string    $table         name of table that should be used in method
65      * @param string    $field_name     name of field that should be used in method
66      * @return mixed data array on success, a MDB2 error on failure
67      * @access public
68      */
69     function getTableFieldDefinition($table, $field_name)
70     {
71         $db =& $this->getDBInstance();
72         if (PEAR::isError($db)) {
73             return $db;
74         }
75
76         $result = $db->loadModule('Datatype');
77         if (PEAR::isError($result)) {
78             return $result;
79         }
80         $columns = $db->queryAll("SHOW COLUMNS FROM $table", null, MDB2_FETCHMODE_ASSOC);
81         if (PEAR::isError($columns)) {
82             return $columns;
83         }
84         foreach ($columns as $column) {
85             if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
86                 if ($db->options['field_case'] == CASE_LOWER) {
87                     $column['field'] = strtolower($column['field']);
88                 } else {
89                     $column['field'] = strtoupper($column['field']);
90                 }
91             } else {
92                 $column = array_change_key_case($column, $db->options['field_case']);
93             }
94             if ($field_name == $column['field']) {
95                 list($types, $length) = $db->datatype->mapNativeDatatype($column);
96                 $notnull = false;
97                 if (array_key_exists('null', $column) && $column['null'] != 'YES') {
98                     $notnull = true;
99                 }
100                 $default = false;
101                 if (array_key_exists('default', $column)) {
102                     $default = $column['default'];
103                     if (is_null($default) && $notnull) {
104                         $default = '';
105                     }
106                 }
107                 $autoincrement = false;
108                 if (array_key_exists('extra', $column) && $column['extra'] == 'auto_increment') {
109                     $autoincrement = true;
110                 }
111                 $definition = array();
112                 foreach ($types as $key => $type) {
113                     $definition[$key] = array(
114                         'type' => $type,
115                         'notnull' => $notnull,
116                     );
117                     if ($length > 0) {
118                         $definition[$key]['length'] = $length;
119                     }
120                     if ($default !== false) {
121                         $definition[$key]['default'] = $default;
122                     }
123                     if ($autoincrement !== false) {
124                         $definition[$key]['autoincrement'] = $autoincrement;
125                     }
126                 }
127                 return $definition;
128             }
129         }
130
131         return $db->raiseError(MDB2_ERROR, null, null,
132             'getTableFieldDefinition: it was not specified an existing table column');
133     }
134
135     // }}}
136     // {{{ getTableIndexDefinition()
137
138     /**
139      * get the stucture of an index into an array
140      *
141      * @param string    $table      name of table that should be used in method
142      * @param string    $index_name name of index that should be used in method
143      * @return mixed data array on success, a MDB2 error on failure
144      * @access public
145      */
146     function getTableIndexDefinition($table, $index_name)
147     {
148         $db =& $this->getDBInstance();
149         if (PEAR::isError($db)) {
150             return $db;
151         }
152
153         $result = $db->query("SHOW INDEX FROM $table");
154         if (PEAR::isError($result)) {
155             return $result;
156         }
157         $definition = array();
158         while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
159             if (!($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE)
160                 || $db->options['field_case'] != CASE_LOWER
161             ) {
162                 $row = array_change_key_case($row, CASE_LOWER);
163             }
164             $key_name = $row['key_name'];
165             if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
166                 if ($db->options['field_case'] == CASE_LOWER) {
167                     $key_name = strtolower($key_name);
168                 } else {
169                     $key_name = strtoupper($key_name);
170                 }
171             }
172             if ($index_name == $key_name) {
173                 if ($row['key_name'] == 'PRIMARY') {
174                     $definition['primary'] = true;
175                 } elseif (!$row['non_unique']) {
176                     $definition['unique'] = true;
177                 }
178                 $column_name = $row['column_name'];
179                 if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
180                     if ($db->options['field_case'] == CASE_LOWER) {
181                         $column_name = strtolower($column_name);
182                     } else {
183                         $column_name = strtoupper($column_name);
184                     }
185                 }
186                 $definition['fields'][$column_name] = array();
187                 if (array_key_exists('collation', $row)) {
188                     $definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
189                         ? 'ascending' : 'descending');
190                 }
191             }
192         }
193         $result->free();
194         if (!array_key_exists('fields', $definition)) {
195             return $db->raiseError(MDB2_ERROR, null, null,
196                 'getTableIndexDefinition: it was not specified an existing table index');
197         }
198         return $definition;
199     }
200
201     // }}}
202     // {{{ tableInfo()
203
204     /**
205      * Returns information about a table or a result set
206      *
207      * @param object|string  $result  MDB2_result object from a query or a
208      *                                 string containing the name of a table.
209      *                                 While this also accepts a query result
210      *                                 resource identifier, this behavior is
211      *                                 deprecated.
212      * @param int            $mode    a valid tableInfo mode
213      *
214      * @return array  an associative array with the information requested.
215      *                 A MDB2_Error object on failure.
216      *
217      * @see MDB2_Driver_Common::setOption()
218      */
219     function tableInfo($result, $mode = null)
220     {
221         $db =& $this->getDBInstance();
222         if (PEAR::isError($db)) {
223             return $db;
224         }
225
226         if (is_string($result)) {
227             /*
228              * Probably received a table name.
229              * Create a result resource identifier.
230              */
231             $connected = $db->connect();
232             if (PEAR::isError($connected)) {
233                 return $connected;
234             }
235             $id = @mysql_list_fields($db->database_name, $result, $db->connection);
236             $got_string = true;
237         } elseif (MDB2::isResultCommon($result)) {
238             /*
239              * Probably received a result object.
240              * Extract the result resource identifier.
241              */
242             $id = $result->getResource();
243             $got_string = false;
244         } else {
245             /*
246              * Probably received a result resource identifier.
247              * Copy it.
248              * Deprecated.  Here for compatibility only.
249              */
250             $id = $result;
251             $got_string = false;
252         }
253
254         if (!is_resource($id)) {
255             return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
256         }
257
258         if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
259             if ($db->options['field_case'] == CASE_LOWER) {
260                 $case_func = 'strtolower';
261             } else {
262                 $case_func = 'strtoupper';
263             }
264         } else {
265             $case_func = 'strval';
266         }
267
268         $count = @mysql_num_fields($id);
269         $res   = array();
270
271         if ($mode) {
272             $res['num_fields'] = $count;
273         }
274
275         for ($i = 0; $i < $count; $i++) {
276             $res[$i] = array(
277                 'table' => $case_func(@mysql_field_table($id, $i)),
278                 'name'  => $case_func(@mysql_field_name($id, $i)),
279                 'type'  => @mysql_field_type($id, $i),
280                 'len'   => @mysql_field_len($id, $i),
281                 'flags' => @mysql_field_flags($id, $i),
282             );
283             if ($mode & MDB2_TABLEINFO_ORDER) {
284                 $res['order'][$res[$i]['name']] = $i;
285             }
286             if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
287                 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
288             }
289         }
290
291         // free the result only if we were called on a table
292         if ($got_string) {
293             @mysql_free_result($id);
294         }
295         return $res;
296     }
297 }
298 ?>