Subversion-Projekte lars-tiefland.php_share

Revision

Details | 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.35 2007/02/25 11:14:34 quipo 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 structure of a field into an array
77
     *
78
     * @param string    $table     name of table that should be used in method
79
     * @param string    $field     name of field that should be used in method
80
     * @return mixed data array on success, a MDB2 error on failure.
81
     *          The returned array contains an array for each field definition,
82
     *          with all or some of these indices, depending on the field data type:
83
     *          [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
84
     * @access public
85
     */
86
    function getTableFieldDefinition($table, $field)
87
    {
88
        $db =& $this->getDBInstance();
89
        if (PEAR::isError($db)) {
90
            return $db;
91
        }
92
 
93
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
94
            'method not implemented', __FUNCTION__);
95
    }
96
 
97
    // }}}
98
    // {{{ getTableIndexDefinition()
99
 
100
    /**
101
     * Get the structure of an index into an array
102
     *
103
     * @param string    $table      name of table that should be used in method
104
     * @param string    $index      name of index that should be used in method
105
     * @return mixed data array on success, a MDB2 error on failure
106
     *          The returned array has this structure:
107
     *          </pre>
108
     *          array (
109
     *              [fields] => array (
110
     *                  [field1name] => array() // one entry per each field covered
111
     *                  [field2name] => array() // by the index
112
     *                  [field3name] => array(
113
     *                      [sorting] => ascending
114
     *                  )
115
     *              )
116
     *          );
117
     *          </pre>
118
     * @access public
119
     */
120
    function getTableIndexDefinition($table, $index)
121
    {
122
        $db =& $this->getDBInstance();
123
        if (PEAR::isError($db)) {
124
            return $db;
125
        }
126
 
127
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
128
            'method not implemented', __FUNCTION__);
129
    }
130
 
131
    // }}}
132
    // {{{ getTableConstraintDefinition()
133
 
134
    /**
135
     * Get the structure of an constraints into an array
136
     *
137
     * @param string    $table      name of table that should be used in method
138
     * @param string    $index      name of index that should be used in method
139
     * @return mixed data array on success, a MDB2 error on failure
140
     *          The returned array has this structure:
141
     *          <pre>
142
     *          array (
143
     *              [primary] => 1
144
     *              [fields] => array (
145
     *                  [field1name] => array() // one entry per each field covered
146
     *                  [field2name] => array() // by the index
147
     *                  [field3name] => array(
148
     *                      [sorting] => ascending
149
     *                  )
150
     *              )
151
     *          );
152
     *          </pre>
153
     * @access public
154
     */
155
    function getTableConstraintDefinition($table, $index)
156
    {
157
        $db =& $this->getDBInstance();
158
        if (PEAR::isError($db)) {
159
            return $db;
160
        }
161
 
162
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
163
            'method not implemented', __FUNCTION__);
164
    }
165
 
166
    // }}}
167
    // {{{ getSequenceDefinition()
168
 
169
    /**
170
     * Get the structure of a sequence into an array
171
     *
172
     * @param string    $sequence   name of sequence that should be used in method
173
     * @return mixed data array on success, a MDB2 error on failure
174
     *          The returned array has this structure:
175
     *          <pre>
176
     *          array (
177
     *              [start] => n
178
     *          );
179
     *          </pre>
180
     * @access public
181
     */
182
    function getSequenceDefinition($sequence)
183
    {
184
        $db =& $this->getDBInstance();
185
        if (PEAR::isError($db)) {
186
            return $db;
187
        }
188
 
189
        $start = $db->currId($sequence);
190
        if (PEAR::isError($start)) {
191
            return $start;
192
        }
193
        if ($db->supports('current_id')) {
194
            $start++;
195
        } else {
196
            $db->warnings[] = 'database does not support getting current
197
                sequence value, the sequence value was incremented';
198
        }
199
        $definition = array();
200
        if ($start != 1) {
201
            $definition = array('start' => $start);
202
        }
203
        return $definition;
204
    }
205
 
206
    // }}}
207
    // {{{ getTriggerDefinition()
208
 
209
    /**
210
     * Get the structure of a trigger into an array
211
     *
212
     * EXPERIMENTAL
213
     *
214
     * WARNING: this function is experimental and may change the returned value
215
     * at any time until labelled as non-experimental
216
     *
217
     * @param string    $trigger    name of trigger that should be used in method
218
     * @return mixed data array on success, a MDB2 error on failure
219
     *          The returned array has this structure:
220
     *          <pre>
221
     *          array (
222
     *              [trigger_name]    => 'trigger name',
223
     *              [table_name]      => 'table name',
224
     *              [trigger_body]    => 'trigger body definition',
225
     *              [trigger_type]    => 'BEFORE' | 'AFTER',
226
     *              [trigger_event]   => 'INSERT' | 'UPDATE' | 'DELETE'
227
     *                  //or comma separated list of multiple events, when supported
228
     *              [trigger_enabled] => true|false
229
     *              [trigger_comment] => 'trigger comment',
230
     *          );
231
     *          </pre>
232
     *          The oci8 driver also returns a [when_clause] index.
233
     * @access public
234
     */
235
    function getTriggerDefinition($trigger)
236
    {
237
        $db =& $this->getDBInstance();
238
        if (PEAR::isError($db)) {
239
            return $db;
240
        }
241
 
242
        return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
243
            'method not implemented', __FUNCTION__);
244
    }
245
 
246
    // }}}
247
    // {{{ tableInfo()
248
 
249
    /**
250
     * Returns information about a table or a result set
251
     *
252
     * The format of the resulting array depends on which <var>$mode</var>
253
     * you select.  The sample output below is based on this query:
254
     * <pre>
255
     *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
256
     *    FROM tblFoo
257
     *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
258
     * </pre>
259
     *
260
     * <ul>
261
     * <li>
262
     *
263
     * <kbd>null</kbd> (default)
264
     *   <pre>
265
     *   [0] => Array (
266
     *       [table] => tblFoo
267
     *       [name] => fldId
268
     *       [type] => int
269
     *       [len] => 11
270
     *       [flags] => primary_key not_null
271
     *   )
272
     *   [1] => Array (
273
     *       [table] => tblFoo
274
     *       [name] => fldPhone
275
     *       [type] => string
276
     *       [len] => 20
277
     *       [flags] =>
278
     *   )
279
     *   [2] => Array (
280
     *       [table] => tblBar
281
     *       [name] => fldId
282
     *       [type] => int
283
     *       [len] => 11
284
     *       [flags] => primary_key not_null
285
     *   )
286
     *   </pre>
287
     *
288
     * </li><li>
289
     *
290
     * <kbd>MDB2_TABLEINFO_ORDER</kbd>
291
     *
292
     *   <p>In addition to the information found in the default output,
293
     *   a notation of the number of columns is provided by the
294
     *   <samp>num_fields</samp> element while the <samp>order</samp>
295
     *   element provides an array with the column names as the keys and
296
     *   their location index number (corresponding to the keys in the
297
     *   the default output) as the values.</p>
298
     *
299
     *   <p>If a result set has identical field names, the last one is
300
     *   used.</p>
301
     *
302
     *   <pre>
303
     *   [num_fields] => 3
304
     *   [order] => Array (
305
     *       [fldId] => 2
306
     *       [fldTrans] => 1
307
     *   )
308
     *   </pre>
309
     *
310
     * </li><li>
311
     *
312
     * <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>
313
     *
314
     *   <p>Similar to <kbd>MDB2_TABLEINFO_ORDER</kbd> but adds more
315
     *   dimensions to the array in which the table names are keys and
316
     *   the field names are sub-keys.  This is helpful for queries that
317
     *   join tables which have identical field names.</p>
318
     *
319
     *   <pre>
320
     *   [num_fields] => 3
321
     *   [ordertable] => Array (
322
     *       [tblFoo] => Array (
323
     *           [fldId] => 0
324
     *           [fldPhone] => 1
325
     *       )
326
     *       [tblBar] => Array (
327
     *           [fldId] => 2
328
     *       )
329
     *   )
330
     *   </pre>
331
     *
332
     * </li>
333
     * </ul>
334
     *
335
     * The <samp>flags</samp> element contains a space separated list
336
     * of extra information about the field.  This data is inconsistent
337
     * between DBMS's due to the way each DBMS works.
338
     *   + <samp>primary_key</samp>
339
     *   + <samp>unique_key</samp>
340
     *   + <samp>multiple_key</samp>
341
     *   + <samp>not_null</samp>
342
     *
343
     * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
344
     * elements if <var>$result</var> is a table name.  The following DBMS's
345
     * provide full information from queries:
346
     *   + fbsql
347
     *   + mysql
348
     *
349
     * If the 'portability' option has <samp>MDB2_PORTABILITY_FIX_CASE</samp>
350
     * turned on, the names of tables and fields will be lower or upper cased.
351
     *
352
     * @param object|string  $result  MDB2_result object from a query or a
353
     *                                string containing the name of a table.
354
     *                                While this also accepts a query result
355
     *                                resource identifier, this behavior is
356
     *                                deprecated.
357
     * @param int  $mode   either unused or one of the tableInfo modes:
358
     *                     <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>,
359
     *                     <kbd>MDB2_TABLEINFO_ORDER</kbd> or
360
     *                     <kbd>MDB2_TABLEINFO_FULL</kbd> (which does both).
361
     *                     These are bitwise, so the first two can be
362
     *                     combined using <kbd>|</kbd>.
363
     *
364
     * @return array  an associative array with the information requested.
365
     *                 A MDB2_Error object on failure.
366
     *
367
     * @see MDB2_Driver_Common::setOption()
368
     */
369
    function tableInfo($result, $mode = null)
370
    {
371
        $db =& $this->getDBInstance();
372
        if (PEAR::isError($db)) {
373
            return $db;
374
        }
375
 
376
        if (!is_string($result)) {
377
            return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
378
                'method not implemented', __FUNCTION__);
379
        }
380
 
381
        $db->loadModule('Manager', null, true);
382
        $fields = $db->manager->listTableFields($result);
383
        if (PEAR::isError($fields)) {
384
            return $fields;
385
        }
386
 
387
        $flags = array();
388
 
389
        $idxname_format = $db->getOption('idxname_format');
390
        $db->setOption('idxname_format', '%s');
391
 
392
        $indexes = $db->manager->listTableIndexes($result);
393
        if (PEAR::isError($indexes)) {
394
            $db->setOption('idxname_format', $idxname_format);
395
            return $indexes;
396
        }
397
 
398
        foreach ($indexes as $index) {
399
            $definition = $this->getTableIndexDefinition($result, $index);
400
            if (PEAR::isError($definition)) {
401
                $db->setOption('idxname_format', $idxname_format);
402
                return $definition;
403
            }
404
            if (count($definition['fields']) > 1) {
405
                foreach ($definition['fields'] as $field => $sort) {
406
                    $flags[$field] = 'multiple_key';
407
                }
408
            }
409
        }
410
 
411
        $constraints = $db->manager->listTableConstraints($result);
412
        if (PEAR::isError($constraints)) {
413
            return $constraints;
414
        }
415
 
416
        foreach ($constraints as $constraint) {
417
            $definition = $this->getTableConstraintDefinition($result, $constraint);
418
            if (PEAR::isError($definition)) {
419
                $db->setOption('idxname_format', $idxname_format);
420
                return $definition;
421
            }
422
            $flag = !empty($definition['primary'])
423
                ? 'primary_key' : (!empty($definition['unique'])
424
                    ? 'unique_key' : false);
425
            if ($flag) {
426
                foreach ($definition['fields'] as $field => $sort) {
427
                    if (empty($flags[$field]) || $flags[$field] != 'primary_key') {
428
                        $flags[$field] = $flag;
429
                    }
430
                }
431
            }
432
        }
433
 
434
        if ($mode) {
435
            $res['num_fields'] = count($fields);
436
        }
437
 
438
        foreach ($fields as $i => $field) {
439
            $definition = $this->getTableFieldDefinition($result, $field);
440
            if (PEAR::isError($definition)) {
441
                $db->setOption('idxname_format', $idxname_format);
442
                return $definition;
443
            }
444
            $res[$i] = $definition[0];
445
            $res[$i]['name'] = $field;
446
            $res[$i]['table'] = $result;
447
            $res[$i]['type'] = preg_replace('/^([a-z]+).*$/i', '\\1', trim($definition[0]['nativetype']));
448
            // 'primary_key', 'unique_key', 'multiple_key'
449
            $res[$i]['flags'] = empty($flags[$field]) ? '' : $flags[$field];
450
            // not_null', 'unsigned', 'auto_increment', 'default_[rawencodedvalue]'
451
            if (!empty($res[$i]['notnull'])) {
452
                $res[$i]['flags'].= ' not_null';
453
            }
454
            if (!empty($res[$i]['unsigned'])) {
455
                $res[$i]['flags'].= ' unsigned';
456
            }
457
            if (!empty($res[$i]['auto_increment'])) {
458
                $res[$i]['flags'].= ' autoincrement';
459
            }
460
            if (!empty($res[$i]['default'])) {
461
                $res[$i]['flags'].= ' default_'.rawurlencode($res[$i]['default']);
462
            }
463
 
464
            if ($mode & MDB2_TABLEINFO_ORDER) {
465
                $res['order'][$res[$i]['name']] = $i;
466
            }
467
            if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
468
                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
469
            }
470
        }
471
 
472
        $db->setOption('idxname_format', $idxname_format);
473
        return $res;
474
    }
475
}
476
?>