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: mysql.php,v 1.86 2006/09/26 13:57:11 quipo Exp $
46
//
47
 
48
require_once 'MDB2/Driver/Manager/Common.php';
49
 
50
/**
51
 * MDB2 MySQL driver for the management modules
52
 *
53
 * @package MDB2
54
 * @category Database
55
 * @author  Lukas Smith <smith@pooteeweet.org>
56
 */
57
class MDB2_Driver_Manager_mysql extends MDB2_Driver_Manager_Common
58
{
59
 
60
    // }}}
61
    // {{{ createDatabase()
62
 
63
    /**
64
     * create a new database
65
     *
66
     * @param string $name name of the database that should be created
67
     * @return mixed MDB2_OK on success, a MDB2 error on failure
68
     * @access public
69
     */
70
    function createDatabase($name)
71
    {
72
        $db =& $this->getDBInstance();
73
        if (PEAR::isError($db)) {
74
            return $db;
75
        }
76
 
77
        $name = $db->quoteIdentifier($name, true);
78
        $query = "CREATE DATABASE $name";
79
        $result = $db->exec($query);
80
        if (PEAR::isError($result)) {
81
            return $result;
82
        }
83
        return MDB2_OK;
84
    }
85
 
86
    // }}}
87
    // {{{ dropDatabase()
88
 
89
    /**
90
     * drop an existing database
91
     *
92
     * @param string $name name of the database that should be dropped
93
     * @return mixed MDB2_OK on success, a MDB2 error on failure
94
     * @access public
95
     */
96
    function dropDatabase($name)
97
    {
98
        $db =& $this->getDBInstance();
99
        if (PEAR::isError($db)) {
100
            return $db;
101
        }
102
 
103
        $name = $db->quoteIdentifier($name, true);
104
        $query = "DROP DATABASE $name";
105
        $result = $db->exec($query);
106
        if (PEAR::isError($result)) {
107
            return $result;
108
        }
109
        return MDB2_OK;
110
    }
111
 
112
    // }}}
113
    // {{{ createTable()
114
 
115
    /**
116
     * create a new table
117
     *
118
     * @param string $name   Name of the database that should be created
119
     * @param array $fields  Associative array that contains the definition of each field of the new table
120
     *                       The indexes of the array entries are the names of the fields of the table an
121
     *                       the array entry values are associative arrays like those that are meant to be
122
     *                       passed with the field definitions to get[Type]Declaration() functions.
123
     *                          array(
124
     *                              'id' => array(
125
     *                                  'type' => 'integer',
126
     *                                  'unsigned' => 1
127
     *                                  'notnull' => 1
128
     *                                  'default' => 0
129
     *                              ),
130
     *                              'name' => array(
131
     *                                  'type' => 'text',
132
     *                                  'length' => 12
133
     *                              ),
134
     *                              'password' => array(
135
     *                                  'type' => 'text',
136
     *                                  'length' => 12
137
     *                              )
138
     *                          );
139
     * @param array $options  An associative array of table options:
140
     *                          array(
141
     *                              'comment' => 'Foo',
142
     *                              'character_set' => 'utf8',
143
     *                              'collate' => 'utf8_unicode_ci',
144
     *                              'collate' => 'utf8_unicode_ci',
145
     *                              'type'    => 'innodb',
146
     *                          );
147
     *
148
     * @return mixed MDB2_OK on success, a MDB2 error on failure
149
     * @access public
150
     */
151
    function createTable($name, $fields, $options = array())
152
    {
153
        $db =& $this->getDBInstance();
154
        if (PEAR::isError($db)) {
155
            return $db;
156
        }
157
        $query = $this->_getCreateTableQuery($name, $fields, $options);
158
        if (PEAR::isError($query)) {
159
            return $query;
160
        }
161
 
162
        $options_strings = array();
163
 
164
        if (!empty($options['comment'])) {
165
            $options_strings['comment'] = 'COMMENT = '.$db->quote($options['comment'], 'text');
166
        }
167
 
168
        if (!empty($options['charset'])) {
169
            $options_strings['charset'] = 'DEFAULT CHARACTER SET '.$options['charset'];
170
            if (!empty($options['collate'])) {
171
                $options_strings['charset'].= ' COLLATE '.$options['collate'];
172
            }
173
        }
174
 
175
        $type = false;
176
        if (!empty($options['type'])) {
177
            $type = $options['type'];
178
        } elseif ($db->options['default_table_type']) {
179
            $type = $db->options['default_table_type'];
180
        }
181
        if ($type) {
182
            $options_strings[] = "ENGINE = $type";
183
        }
184
 
185
        if (!empty($options_strings)) {
186
            $query.= ' '.implode(' ', $options_strings);
187
        }
188
        return $db->exec($query);
189
    }
190
 
191
    // }}}
192
    // {{{ alterTable()
193
 
194
    /**
195
     * alter an existing table
196
     *
197
     * @param string $name         name of the table that is intended to be changed.
198
     * @param array $changes     associative array that contains the details of each type
199
     *                             of change that is intended to be performed. The types of
200
     *                             changes that are currently supported are defined as follows:
201
     *
202
     *                             name
203
     *
204
     *                                New name for the table.
205
     *
206
     *                            add
207
     *
208
     *                                Associative array with the names of fields to be added as
209
     *                                 indexes of the array. The value of each entry of the array
210
     *                                 should be set to another associative array with the properties
211
     *                                 of the fields to be added. The properties of the fields should
212
     *                                 be the same as defined by the MDB2 parser.
213
     *
214
     *
215
     *                            remove
216
     *
217
     *                                Associative array with the names of fields to be removed as indexes
218
     *                                 of the array. Currently the values assigned to each entry are ignored.
219
     *                                 An empty array should be used for future compatibility.
220
     *
221
     *                            rename
222
     *
223
     *                                Associative array with the names of fields to be renamed as indexes
224
     *                                 of the array. The value of each entry of the array should be set to
225
     *                                 another associative array with the entry named name with the new
226
     *                                 field name and the entry named Declaration that is expected to contain
227
     *                                 the portion of the field declaration already in DBMS specific SQL code
228
     *                                 as it is used in the CREATE TABLE statement.
229
     *
230
     *                            change
231
     *
232
     *                                Associative array with the names of the fields to be changed as indexes
233
     *                                 of the array. Keep in mind that if it is intended to change either the
234
     *                                 name of a field and any other properties, the change array entries
235
     *                                 should have the new names of the fields as array indexes.
236
     *
237
     *                                The value of each entry of the array should be set to another associative
238
     *                                 array with the properties of the fields to that are meant to be changed as
239
     *                                 array entries. These entries should be assigned to the new values of the
240
     *                                 respective properties. The properties of the fields should be the same
241
     *                                 as defined by the MDB2 parser.
242
     *
243
     *                            Example
244
     *                                array(
245
     *                                    'name' => 'userlist',
246
     *                                    'add' => array(
247
     *                                        'quota' => array(
248
     *                                            'type' => 'integer',
249
     *                                            'unsigned' => 1
250
     *                                        )
251
     *                                    ),
252
     *                                    'remove' => array(
253
     *                                        'file_limit' => array(),
254
     *                                        'time_limit' => array()
255
     *                                    ),
256
     *                                    'change' => array(
257
     *                                        'name' => array(
258
     *                                            'length' => '20',
259
     *                                            'definition' => array(
260
     *                                                'type' => 'text',
261
     *                                                'length' => 20,
262
     *                                            ),
263
     *                                        )
264
     *                                    ),
265
     *                                    'rename' => array(
266
     *                                        'sex' => array(
267
     *                                            'name' => 'gender',
268
     *                                            'definition' => array(
269
     *                                                'type' => 'text',
270
     *                                                'length' => 1,
271
     *                                                'default' => 'M',
272
     *                                            ),
273
     *                                        )
274
     *                                    )
275
     *                                )
276
     *
277
     * @param boolean $check     indicates whether the function should just check if the DBMS driver
278
     *                             can perform the requested table alterations if the value is true or
279
     *                             actually perform them otherwise.
280
     * @access public
281
     *
282
      * @return mixed MDB2_OK on success, a MDB2 error on failure
283
     */
284
    function alterTable($name, $changes, $check)
285
    {
286
        $db =& $this->getDBInstance();
287
        if (PEAR::isError($db)) {
288
            return $db;
289
        }
290
 
291
        foreach ($changes as $change_name => $change) {
292
            switch ($change_name) {
293
            case 'add':
294
            case 'remove':
295
            case 'change':
296
            case 'rename':
297
            case 'name':
298
                break;
299
            default:
300
                return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
301
                    'change type "'.$change_name.'" not yet supported', __FUNCTION__);
302
            }
303
        }
304
 
305
        if ($check) {
306
            return MDB2_OK;
307
        }
308
 
309
        $query = '';
310
        if (!empty($changes['name'])) {
311
            $change_name = $db->quoteIdentifier($changes['name'], true);
312
            $query .= 'RENAME TO ' . $change_name;
313
        }
314
 
315
        if (!empty($changes['add']) && is_array($changes['add'])) {
316
            foreach ($changes['add'] as $field_name => $field) {
317
                if ($query) {
318
                    $query.= ', ';
319
                }
320
                $query.= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
321
            }
322
        }
323
 
324
        if (!empty($changes['remove']) && is_array($changes['remove'])) {
325
            foreach ($changes['remove'] as $field_name => $field) {
326
                if ($query) {
327
                    $query.= ', ';
328
                }
329
                $field_name = $db->quoteIdentifier($field_name, true);
330
                $query.= 'DROP ' . $field_name;
331
            }
332
        }
333
 
334
        $rename = array();
335
        if (!empty($changes['rename']) && is_array($changes['rename'])) {
336
            foreach ($changes['rename'] as $field_name => $field) {
337
                $rename[$field['name']] = $field_name;
338
            }
339
        }
340
 
341
        if (!empty($changes['change']) && is_array($changes['change'])) {
342
            foreach ($changes['change'] as $field_name => $field) {
343
                if ($query) {
344
                    $query.= ', ';
345
                }
346
                if (isset($rename[$field_name])) {
347
                    $old_field_name = $rename[$field_name];
348
                    unset($rename[$field_name]);
349
                } else {
350
                    $old_field_name = $field_name;
351
                }
352
                $old_field_name = $db->quoteIdentifier($old_field_name, true);
353
                $query.= "CHANGE $old_field_name " . $db->getDeclaration($field['definition']['type'], $field_name, $field['definition']);
354
            }
355
        }
356
 
357
        if (!empty($rename) && is_array($rename)) {
358
            foreach ($rename as $rename_name => $renamed_field) {
359
                if ($query) {
360
                    $query.= ', ';
361
                }
362
                $field = $changes['rename'][$renamed_field];
363
                $renamed_field = $db->quoteIdentifier($renamed_field, true);
364
                $query.= 'CHANGE ' . $renamed_field . ' ' . $db->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
365
            }
366
        }
367
 
368
        if (!$query) {
369
            return MDB2_OK;
370
        }
371
 
372
        $name = $db->quoteIdentifier($name, true);
373
        return $db->exec("ALTER TABLE $name $query");
374
    }
375
 
376
    // }}}
377
    // {{{ listDatabases()
378
 
379
    /**
380
     * list all databases
381
     *
382
     * @return mixed data array on success, a MDB2 error on failure
383
     * @access public
384
     */
385
    function listDatabases()
386
    {
387
        $db =& $this->getDBInstance();
388
        if (PEAR::isError($db)) {
389
            return $db;
390
        }
391
 
392
        $result = $db->queryCol('SHOW DATABASES');
393
        if (PEAR::isError($result)) {
394
            return $result;
395
        }
396
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
397
            $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
398
        }
399
        return $result;
400
    }
401
 
402
    // }}}
403
    // {{{ listUsers()
404
 
405
    /**
406
     * list all users
407
     *
408
     * @return mixed data array on success, a MDB2 error on failure
409
     * @access public
410
     */
411
    function listUsers()
412
    {
413
        $db =& $this->getDBInstance();
414
        if (PEAR::isError($db)) {
415
            return $db;
416
        }
417
 
418
        return $db->queryCol('SELECT DISTINCT USER FROM USER');
419
    }
420
 
421
    // }}}
422
    // {{{ listTables()
423
 
424
    /**
425
     * list all tables in the current database
426
     *
427
     * @param string database, the current is default
428
     * @return mixed data array on success, a MDB2 error on failure
429
     * @access public
430
     */
431
    function listTables($database = null)
432
    {
433
        $db =& $this->getDBInstance();
434
        if (PEAR::isError($db)) {
435
            return $db;
436
        }
437
 
438
        $query = "SHOW /*!50002 FULL*/ TABLES";
439
        if (!is_null($database)) {
440
            $query .= " FROM $database";
441
        }
442
        $query.= "/*!50002  WHERE Table_type = 'BASE TABLE'*/";
443
 
444
        $table_names = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED);
445
        if (PEAR::isError($table_names)) {
446
            return $table_names;
447
        }
448
 
449
        $result = array();
450
        foreach ($table_names as $table) {
451
            if (!$this->_fixSequenceName($table[0], true)) {
452
                $result[] = $table[0];
453
            }
454
        }
455
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
456
            $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
457
        }
458
        return $result;
459
    }
460
 
461
    // }}}
462
    // {{{ listViews()
463
 
464
    /**
465
     * list the views in the database
466
     *
467
     * @param string database, the current is default
468
     * @return mixed MDB2_OK on success, a MDB2 error on failure
469
     * @access public
470
     **/
471
    function listViews($database = null)
472
    {
473
        $db =& $this->getDBInstance();
474
        if (PEAR::isError($db)) {
475
            return $db;
476
        }
477
 
478
        $query = 'SHOW FULL TABLES';
479
        if (!is_null($database)) {
480
            $query.= " FROM $database";
481
        }
482
        $query.= " WHERE Table_type = 'VIEW'";
483
 
484
        $result = $db->queryCol($query);
485
        if (PEAR::isError($result)) {
486
            return $result;
487
        }
488
 
489
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
490
            $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
491
        }
492
        return $result;
493
    }
494
 
495
    // }}}
496
    // {{{ listTableFields()
497
 
498
    /**
499
     * list all fields in a tables in the current database
500
     *
501
     * @param string $table name of table that should be used in method
502
     * @return mixed data array on success, a MDB2 error on failure
503
     * @access public
504
     */
505
    function listTableFields($table)
506
    {
507
        $db =& $this->getDBInstance();
508
        if (PEAR::isError($db)) {
509
            return $db;
510
        }
511
 
512
        $table = $db->quoteIdentifier($table, true);
513
        $result = $db->queryCol("SHOW COLUMNS FROM $table");
514
        if (PEAR::isError($result)) {
515
            return $result;
516
        }
517
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
518
            $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
519
        }
520
        return $result;
521
    }
522
 
523
    // }}}
524
    // {{{ createIndex()
525
 
526
    /**
527
     * Get the stucture of a field into an array
528
     *
529
     * @author Leoncx
530
     * @param string    $table         name of the table on which the index is to be created
531
     * @param string    $name         name of the index to be created
532
     * @param array     $definition        associative array that defines properties of the index to be created.
533
     *                                 Currently, only one property named FIELDS is supported. This property
534
     *                                 is also an associative with the names of the index fields as array
535
     *                                 indexes. Each entry of this array is set to another type of associative
536
     *                                 array that specifies properties of the index that are specific to
537
     *                                 each field.
538
     *
539
     *                                Currently, only the sorting property is supported. It should be used
540
     *                                 to define the sorting direction of the index. It may be set to either
541
     *                                 ascending or descending.
542
     *
543
     *                                Not all DBMS support index sorting direction configuration. The DBMS
544
     *                                 drivers of those that do not support it ignore this property. Use the
545
     *                                 function supports() to determine whether the DBMS driver can manage indexes.
546
     *
547
     *                                 Example
548
     *                                    array(
549
     *                                        'fields' => array(
550
     *                                            'user_name' => array(
551
     *                                                'sorting' => 'ascending'
552
     *                                                'length' => 10
553
     *                                            ),
554
     *                                            'last_login' => array()
555
     *                                        )
556
     *                                    )
557
     * @return mixed MDB2_OK on success, a MDB2 error on failure
558
     * @access public
559
     */
560
    function createIndex($table, $name, $definition)
561
    {
562
        $db =& $this->getDBInstance();
563
        if (PEAR::isError($db)) {
564
            return $db;
565
        }
566
 
567
        $table = $db->quoteIdentifier($table, true);
568
        $name = $db->quoteIdentifier($db->getIndexName($name), true);
569
        $query = "CREATE INDEX $name ON $table";
570
        $fields = array();
571
        foreach ($definition['fields'] as $field => $fieldinfo) {
572
            if (!empty($fieldinfo['length'])) {
573
                $fields[] = $db->quoteIdentifier($field, true) . '(' . $fieldinfo['length'] . ')';
574
            } else {
575
                $fields[] = $db->quoteIdentifier($field, true);
576
            }
577
        }
578
        $query .= ' ('. implode(', ', $fields) . ')';
579
        return $db->exec($query);
580
    }
581
 
582
    // }}}
583
    // {{{ dropIndex()
584
 
585
    /**
586
     * drop existing index
587
     *
588
     * @param string    $table         name of table that should be used in method
589
     * @param string    $name         name of the index to be dropped
590
     * @return mixed MDB2_OK on success, a MDB2 error on failure
591
     * @access public
592
     */
593
    function dropIndex($table, $name)
594
    {
595
        $db =& $this->getDBInstance();
596
        if (PEAR::isError($db)) {
597
            return $db;
598
        }
599
 
600
        $table = $db->quoteIdentifier($table, true);
601
        $name = $db->quoteIdentifier($db->getIndexName($name), true);
602
        return $db->exec("DROP INDEX $name ON $table");
603
    }
604
 
605
    // }}}
606
    // {{{ listTableIndexes()
607
 
608
    /**
609
     * list all indexes in a table
610
     *
611
     * @param string    $table      name of table that should be used in method
612
     * @return mixed data array on success, a MDB2 error on failure
613
     * @access public
614
     */
615
    function listTableIndexes($table)
616
    {
617
        $db =& $this->getDBInstance();
618
        if (PEAR::isError($db)) {
619
            return $db;
620
        }
621
 
622
        $key_name = 'Key_name';
623
        $non_unique = 'Non_unique';
624
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
625
            if ($db->options['field_case'] == CASE_LOWER) {
626
                $key_name = strtolower($key_name);
627
                $non_unique = strtolower($non_unique);
628
            } else {
629
                $key_name = strtoupper($key_name);
630
                $non_unique = strtoupper($non_unique);
631
            }
632
        }
633
 
634
        $table = $db->quoteIdentifier($table, true);
635
        $query = "SHOW INDEX FROM $table";
636
        $indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
637
        if (PEAR::isError($indexes)) {
638
            return $indexes;
639
        }
640
 
641
        $result = array();
642
        foreach ($indexes as $index_data) {
643
            if ($index_data[$non_unique] && ($index = $this->_fixIndexName($index_data[$key_name]))) {
644
                $result[$index] = true;
645
            }
646
        }
647
 
648
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
649
            $result = array_change_key_case($result, $db->options['field_case']);
650
        }
651
        return array_keys($result);
652
    }
653
 
654
    // }}}
655
    // {{{ createConstraint()
656
 
657
    /**
658
     * create a constraint on a table
659
     *
660
     * @param string    $table         name of the table on which the constraint is to be created
661
     * @param string    $name         name of the constraint to be created
662
     * @param array     $definition        associative array that defines properties of the constraint to be created.
663
     *                                 Currently, only one property named FIELDS is supported. This property
664
     *                                 is also an associative with the names of the constraint fields as array
665
     *                                 constraints. Each entry of this array is set to another type of associative
666
     *                                 array that specifies properties of the constraint that are specific to
667
     *                                 each field.
668
     *
669
     *                                 Example
670
     *                                    array(
671
     *                                        'fields' => array(
672
     *                                            'user_name' => array(),
673
     *                                            'last_login' => array()
674
     *                                        )
675
     *                                    )
676
     * @return mixed MDB2_OK on success, a MDB2 error on failure
677
     * @access public
678
     */
679
    function createConstraint($table, $name, $definition)
680
    {
681
        $db =& $this->getDBInstance();
682
        if (PEAR::isError($db)) {
683
            return $db;
684
        }
685
 
686
        $type = '';
687
        $name = $db->quoteIdentifier($db->getIndexName($name), true);
688
        if (!empty($definition['primary'])) {
689
            $type = 'PRIMARY';
690
            $name = 'KEY';
691
        } elseif (!empty($definition['unique'])) {
692
            $type = 'UNIQUE';
693
        }
694
 
695
        $table = $db->quoteIdentifier($table, true);
696
        $query = "ALTER TABLE $table ADD $type $name";
697
        $fields = array();
698
        foreach (array_keys($definition['fields']) as $field) {
699
            $fields[] = $db->quoteIdentifier($field, true);
700
        }
701
        $query .= ' ('. implode(', ', $fields) . ')';
702
        return $db->exec($query);
703
    }
704
 
705
    // }}}
706
    // {{{ dropConstraint()
707
 
708
    /**
709
     * drop existing constraint
710
     *
711
     * @param string    $table        name of table that should be used in method
712
     * @param string    $name         name of the constraint to be dropped
713
     * @param string    $primary      hint if the constraint is primary
714
     * @return mixed MDB2_OK on success, a MDB2 error on failure
715
     * @access public
716
     */
717
    function dropConstraint($table, $name, $primary = false)
718
    {
719
        $db =& $this->getDBInstance();
720
        if (PEAR::isError($db)) {
721
            return $db;
722
        }
723
 
724
        $table = $db->quoteIdentifier($table, true);
725
        if ($primary || strtolower($name) == 'primary') {
726
            $query = "ALTER TABLE $table DROP PRIMARY KEY";
727
        } else {
728
            $name = $db->quoteIdentifier($db->getIndexName($name), true);
729
            $query = "ALTER TABLE $table DROP INDEX $name";
730
        }
731
        return $db->exec($query);
732
    }
733
 
734
    // }}}
735
    // {{{ listTableConstraints()
736
 
737
    /**
738
     * list all constraints in a table
739
     *
740
     * @param string    $table      name of table that should be used in method
741
     * @return mixed data array on success, a MDB2 error on failure
742
     * @access public
743
     */
744
    function listTableConstraints($table)
745
    {
746
        $db =& $this->getDBInstance();
747
        if (PEAR::isError($db)) {
748
            return $db;
749
        }
750
 
751
        $key_name = 'Key_name';
752
        $non_unique = 'Non_unique';
753
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
754
            if ($db->options['field_case'] == CASE_LOWER) {
755
                $key_name = strtolower($key_name);
756
                $non_unique = strtolower($non_unique);
757
            } else {
758
                $key_name = strtoupper($key_name);
759
                $non_unique = strtoupper($non_unique);
760
            }
761
        }
762
 
763
        $table = $db->quoteIdentifier($table, true);
764
        $query = "SHOW INDEX FROM $table";
765
        $indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
766
        if (PEAR::isError($indexes)) {
767
            return $indexes;
768
        }
769
 
770
        $result = array();
771
        foreach ($indexes as $index_data) {
772
            if (!$index_data[$non_unique]) {
773
                if ($index_data[$key_name] !== 'PRIMARY') {
774
                    $index = $this->_fixIndexName($index_data[$key_name]);
775
                } else {
776
                    $index = 'PRIMARY';
777
                }
778
                if (!empty($index)) {
779
                    $result[$index] = true;
780
                }
781
            }
782
        }
783
 
784
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
785
            $result = array_change_key_case($result, $db->options['field_case']);
786
        }
787
        return array_keys($result);
788
    }
789
 
790
    // }}}
791
    // {{{ createSequence()
792
 
793
    /**
794
     * create sequence
795
     *
796
     * @param string    $seq_name     name of the sequence to be created
797
     * @param string    $start         start value of the sequence; default is 1
798
     * @return mixed MDB2_OK on success, a MDB2 error on failure
799
     * @access public
800
     */
801
    function createSequence($seq_name, $start = 1)
802
    {
803
        $db =& $this->getDBInstance();
804
        if (PEAR::isError($db)) {
805
            return $db;
806
        }
807
 
808
        $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true);
809
        $seqcol_name = $db->quoteIdentifier($db->options['seqcol_name'], true);
810
 
811
        $query = "CREATE TABLE $sequence_name ($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))";
812
        $query.= strlen($db->options['default_table_type']) ? ' TYPE='.$db->options['default_table_type'] : '';
813
        $res = $db->exec($query);
814
 
815
        if (PEAR::isError($res)) {
816
            return $res;
817
        }
818
 
819
        if ($start == 1) {
820
            return MDB2_OK;
821
        }
822
 
823
        $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')';
824
        $res = $db->exec($query);
825
        if (!PEAR::isError($res)) {
826
            return MDB2_OK;
827
        }
828
 
829
        // Handle error
830
        $result = $db->exec("DROP TABLE $sequence_name");
831
        if (PEAR::isError($result)) {
832
            return $db->raiseError($result, null, null,
833
                'could not drop inconsistent sequence table', __FUNCTION__);
834
        }
835
 
836
        return $db->raiseError($res, null, null,
837
            'could not create sequence table', __FUNCTION__);
838
    }
839
 
840
    // }}}
841
    // {{{ dropSequence()
842
 
843
    /**
844
     * drop existing sequence
845
     *
846
     * @param string    $seq_name     name of the sequence to be dropped
847
     * @return mixed MDB2_OK on success, a MDB2 error on failure
848
     * @access public
849
     */
850
    function dropSequence($seq_name)
851
    {
852
        $db =& $this->getDBInstance();
853
        if (PEAR::isError($db)) {
854
            return $db;
855
        }
856
 
857
        $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true);
858
        return $db->exec("DROP TABLE $sequence_name");
859
    }
860
 
861
    // }}}
862
    // {{{ listSequences()
863
 
864
    /**
865
     * list all sequences in the current database
866
     *
867
     * @param string database, the current is default
868
     * @return mixed data array on success, a MDB2 error on failure
869
     * @access public
870
     */
871
    function listSequences($database = null)
872
    {
873
        $db =& $this->getDBInstance();
874
        if (PEAR::isError($db)) {
875
            return $db;
876
        }
877
 
878
        $query = "SHOW TABLES";
879
        if (!is_null($database)) {
880
            $query .= " FROM $database";
881
        }
882
        $table_names = $db->queryCol($query);
883
        if (PEAR::isError($table_names)) {
884
            return $table_names;
885
        }
886
 
887
        $result = array();
888
        foreach ($table_names as $table_name) {
889
            if ($sqn = $this->_fixSequenceName($table_name, true)) {
890
                $result[] = $sqn;
891
            }
892
        }
893
        if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
894
            $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
895
        }
896
        return $result;
897
    }
898
 
899
    // }}}
900
}
901
?>