Subversion-Projekte lars-tiefland.niewerth

Revision

Revision 7 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
// +----------------------------------------------------------------------+
3
// | PHP versions 4 and 5                                                 |
4
// +----------------------------------------------------------------------+
5
// | Copyright (c) 1998-2006 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: Common.php,v 1.28 2006/08/15 11:24:51 lsmith Exp $
46
//
47
 
48
/**
49
 * @package MDB2
50
 * @category Database
51
 */
52
 
53
/**
54
 * These are constants for the tableInfo-function
55
 * they are bitwised or'ed. so if there are more constants to be defined
56
 * in the future, adjust MDB2_TABLEINFO_FULL accordingly
57
 */
58
 
59
define('MDB2_TABLEINFO_ORDER',      1);
60
define('MDB2_TABLEINFO_ORDERTABLE', 2);
61
define('MDB2_TABLEINFO_FULL',       3);
62
 
63
/**
64
 * Base class for the schema reverse engineering module that is extended by each MDB2 driver
65
 *
66
 * @package MDB2
67
 * @category Database
68
 * @author  Lukas Smith <smith@pooteeweet.org>
69
 */
70
class MDB2_Driver_Reverse_Common extends MDB2_Module_Common
71
{
72
    // }}}
73
    // {{{ getTableFieldDefinition()
74
 
75
    /**
76
     * Get the stucture of a field into an array
77
     *
78
     * @param string    $table         name of table that should be used in method
79
     * @param string    $fields     name of field that should be used in method
80
     * @return mixed data array on success, a MDB2 error on failure
81
     * @access public
82
     */
83
    function getTableFieldDefinition($table, $field)
84
    {
85
        $db =& $this->getDBInstance();
86
        if (PEAR::isError($db)) {
87
            return $db;
88
        }
89
 
90
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
91
            'method not implemented', __FUNCTION__);
92
    }
93
 
94
    // }}}
95
    // {{{ getTableIndexDefinition()
96
 
97
    /**
98
     * Get the stucture of an index into an array
99
     *
100
     * @param string    $table      name of table that should be used in method
101
     * @param string    $index      name of index that should be used in method
102
     * @return mixed data array on success, a MDB2 error on failure
103
     * @access public
104
     */
105
    function getTableIndexDefinition($table, $index)
106
    {
107
        $db =& $this->getDBInstance();
108
        if (PEAR::isError($db)) {
109
            return $db;
110
        }
111
 
112
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
113
            'method not implemented', __FUNCTION__);
114
    }
115
 
116
    // }}}
117
    // {{{ getTableConstraintDefinition()
118
 
119
    /**
120
     * Get the stucture of an constraints into an array
121
     *
122
     * @param string    $table      name of table that should be used in method
123
     * @param string    $index      name of index that should be used in method
124
     * @return mixed data array on success, a MDB2 error on failure
125
     * @access public
126
     */
127
    function getTableConstraintDefinition($table, $index)
128
    {
129
        $db =& $this->getDBInstance();
130
        if (PEAR::isError($db)) {
131
            return $db;
132
        }
133
 
134
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
135
            'method not implemented', __FUNCTION__);
136
    }
137
 
138
    // }}}
139
    // {{{ getSequenceDefinition()
140
 
141
    /**
142
     * Get the stucture of a sequence into an array
143
     *
144
     * @param string    $sequence   name of sequence that should be used in method
145
     * @return mixed data array on success, a MDB2 error on failure
146
     * @access public
147
     */
148
    function getSequenceDefinition($sequence)
149
    {
150
        $db =& $this->getDBInstance();
151
        if (PEAR::isError($db)) {
152
            return $db;
153
        }
154
 
155
        $start = $db->currId($sequence);
156
        if (PEAR::isError($start)) {
157
            return $start;
158
        }
159
        if ($db->supports('current_id')) {
160
            $start++;
161
        } else {
162
            $db->warnings[] = 'database does not support getting current
163
                sequence value, the sequence value was incremented';
164
        }
165
        $definition = array();
166
        if ($start != 1) {
167
            $definition = array('start' => $start);
168
        }
169
        return $definition;
170
    }
171
 
172
    // }}}
173
    // {{{ getTriggerDefinition()
174
 
175
    /**
176
     * Get the stucture of an trigger into an array
177
     *
178
     * @param string    $trigger    name of trigger that should be used in method
179
     * @return mixed data array on success, a MDB2 error on failure
180
     * @access public
181
     */
182
    function getTriggerDefinition($trigger)
183
    {
184
        $db =& $this->getDBInstance();
185
        if (PEAR::isError($db)) {
186
            return $db;
187
        }
188
 
189
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
190
            'method not implemented', __FUNCTION__);
191
    }
192
 
193
    // }}}
194
    // {{{ tableInfo()
195
 
196
    /**
197
     * Returns information about a table or a result set
198
     *
199
     * The format of the resulting array depends on which <var>$mode</var>
200
     * you select.  The sample output below is based on this query:
201
     * <pre>
202
     *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
203
     *    FROM tblFoo
204
     *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
205
     * </pre>
206
     *
207
     * <ul>
208
     * <li>
209
     *
210
     * <kbd>null</kbd> (default)
211
     *   <pre>
212
     *   [0] => Array (
213
     *       [table] => tblFoo
214
     *       [name] => fldId
215
     *       [type] => int
216
     *       [len] => 11
217
     *       [flags] => primary_key not_null
218
     *   )
219
     *   [1] => Array (
220
     *       [table] => tblFoo
221
     *       [name] => fldPhone
222
     *       [type] => string
223
     *       [len] => 20
224
     *       [flags] =>
225
     *   )
226
     *   [2] => Array (
227
     *       [table] => tblBar
228
     *       [name] => fldId
229
     *       [type] => int
230
     *       [len] => 11
231
     *       [flags] => primary_key not_null
232
     *   )
233
     *   </pre>
234
     *
235
     * </li><li>
236
     *
237
     * <kbd>MDB2_TABLEINFO_ORDER</kbd>
238
     *
239
     *   <p>In addition to the information found in the default output,
240
     *   a notation of the number of columns is provided by the
241
     *   <samp>num_fields</samp> element while the <samp>order</samp>
242
     *   element provides an array with the column names as the keys and
243
     *   their location index number (corresponding to the keys in the
244
     *   the default output) as the values.</p>
245
     *
246
     *   <p>If a result set has identical field names, the last one is
247
     *   used.</p>
248
     *
249
     *   <pre>
250
     *   [num_fields] => 3
251
     *   [order] => Array (
252
     *       [fldId] => 2
253
     *       [fldTrans] => 1
254
     *   )
255
     *   </pre>
256
     *
257
     * </li><li>
258
     *
259
     * <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>
260
     *
261
     *   <p>Similar to <kbd>MDB2_TABLEINFO_ORDER</kbd> but adds more
262
     *   dimensions to the array in which the table names are keys and
263
     *   the field names are sub-keys.  This is helpful for queries that
264
     *   join tables which have identical field names.</p>
265
     *
266
     *   <pre>
267
     *   [num_fields] => 3
268
     *   [ordertable] => Array (
269
     *       [tblFoo] => Array (
270
     *           [fldId] => 0
271
     *           [fldPhone] => 1
272
     *       )
273
     *       [tblBar] => Array (
274
     *           [fldId] => 2
275
     *       )
276
     *   )
277
     *   </pre>
278
     *
279
     * </li>
280
     * </ul>
281
     *
282
     * The <samp>flags</samp> element contains a space separated list
283
     * of extra information about the field.  This data is inconsistent
284
     * between DBMS's due to the way each DBMS works.
285
     *   + <samp>primary_key</samp>
286
     *   + <samp>unique_key</samp>
287
     *   + <samp>multiple_key</samp>
288
     *   + <samp>not_null</samp>
289
     *
290
     * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
291
     * elements if <var>$result</var> is a table name.  The following DBMS's
292
     * provide full information from queries:
293
     *   + fbsql
294
     *   + mysql
295
     *
296
     * If the 'portability' option has <samp>MDB2_PORTABILITY_FIX_CASE</samp>
297
     * turned on, the names of tables and fields will be lower or upper cased.
298
     *
299
     * @param object|string  $result  MDB2_result object from a query or a
300
     *                                string containing the name of a table.
301
     *                                While this also accepts a query result
302
     *                                resource identifier, this behavior is
303
     *                                deprecated.
304
     * @param int  $mode   either unused or one of the tableInfo modes:
305
     *                     <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>,
306
     *                     <kbd>MDB2_TABLEINFO_ORDER</kbd> or
307
     *                     <kbd>MDB2_TABLEINFO_FULL</kbd> (which does both).
308
     *                     These are bitwise, so the first two can be
309
     *                     combined using <kbd>|</kbd>.
310
     *
311
     * @return array  an associative array with the information requested.
312
     *                 A MDB2_Error object on failure.
313
     *
314
     * @see MDB2_Driver_Common::setOption()
315
     */
316
    function tableInfo($result, $mode = null)
317
    {
318
        $db =& $this->getDBInstance();
319
        if (PEAR::isError($db)) {
320
            return $db;
321
        }
322
 
323
        if (!is_string($result)) {
324
            return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
325
                'method not implemented', __FUNCTION__);
326
        }
327
 
328
        $db->loadModule('Manager', null, true);
329
        $fields = $db->manager->listTableFields($result);
330
        if (PEAR::isError($fields)) {
331
            return $fields;
332
        }
333
 
334
        $flags = array();
335
 
336
        $idxname_format = $db->getOption('idxname_format');
337
        $db->setOption('idxname_format', '%s');
338
 
339
        $indexes = $db->manager->listTableIndexes($result);
340
        if (PEAR::isError($indexes)) {
341
            $db->setOption('idxname_format', $idxname_format);
342
            return $indexes;
343
        }
344
 
345
        foreach ($indexes as $index) {
346
            $definition = $this->getTableIndexDefinition($result, $index);
347
            if (PEAR::isError($definition)) {
348
                $db->setOption('idxname_format', $idxname_format);
349
                return $definition;
350
            }
351
            if (count($definition['fields']) > 1) {
352
                foreach ($definition['fields'] as $field => $sort) {
353
                    $flags[$field] = 'multiple_key';
354
                }
355
            }
356
        }
357
 
358
        $constraints = $db->manager->listTableConstraints($result);
359
        if (PEAR::isError($constraints)) {
360
            return $constraints;
361
        }
362
 
363
        foreach ($constraints as $constraint) {
364
            $definition = $this->getTableConstraintDefinition($result, $constraint);
365
            if (PEAR::isError($definition)) {
366
                $db->setOption('idxname_format', $idxname_format);
367
                return $definition;
368
            }
369
            $flag = !empty($definition['primary'])
370
                ? 'primary_key' : (!empty($definition['unique'])
371
                    ? 'unique_key' : false);
372
            if ($flag) {
373
                foreach ($definition['fields'] as $field => $sort) {
374
                    if (empty($flags[$field]) || $flags[$field] != 'primary_key') {
375
                        $flags[$field] = $flag;
376
                    }
377
                }
378
            }
379
        }
380
 
381
        if ($mode) {
382
            $res['num_fields'] = count($fields);
383
        }
384
 
385
        foreach ($fields as $i => $field) {
386
            $definition = $this->getTableFieldDefinition($result, $field);
387
            if (PEAR::isError($definition)) {
388
                $db->setOption('idxname_format', $idxname_format);
389
                return $definition;
390
            }
391
            $res[$i] = $definition[0];
392
            $res[$i]['name'] = $field;
393
            $res[$i]['table'] = $result;
394
            $res[$i]['type'] = preg_replace('/^([a-z]+).*$/i', '\\1', trim($definition[0]['nativetype']));
395
            // 'primary_key', 'unique_key', 'multiple_key'
396
            $res[$i]['flags'] = empty($flags[$field]) ? '' : $flags[$field];
397
            // not_null', 'unsigned', 'auto_increment', 'default_[rawencodedvalue]'
398
            if (!empty($res[$i]['notnull'])) {
399
                $res[$i]['flags'].= ' not_null';
400
            }
401
            if (!empty($res[$i]['unsigned'])) {
402
                $res[$i]['flags'].= ' unsigned';
403
            }
404
            if (!empty($res[$i]['auto_increment'])) {
405
                $res[$i]['flags'].= ' autoincrement';
406
            }
407
            if (!empty($res[$i]['default'])) {
408
                $res[$i]['flags'].= ' default_'.rawurlencode($res[$i]['default']);
409
            }
410
 
411
            if ($mode & MDB2_TABLEINFO_ORDER) {
412
                $res['order'][$res[$i]['name']] = $i;
413
            }
414
            if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
415
                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
416
            }
417
        }
418
 
419
        $db->setOption('idxname_format', $idxname_format);
420
        return $res;
421
    }
422
}
423
?>