Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 1
<?php
2
 
3
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
 
5
/**
6
 * The PEAR DB driver for PHP's msql extension
7
 * for interacting with Mini SQL databases
8
 *
9
 * PHP's mSQL extension did weird things with NULL values prior to PHP
10
 * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
11
 * those versions.
12
 *
187 mathias 13
 * PHP version 5
94 jpm 14
 *
15
 * LICENSE: This source file is subject to version 3.0 of the PHP license
16
 * that is available through the world-wide-web at the following URI:
17
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
18
 * the PHP License and are unable to obtain it through the web, please
19
 * send a note to license@php.net so we can mail you a copy immediately.
20
 *
21
 * @category   Database
22
 * @package    DB
23
 * @author     Daniel Convissor <danielc@php.net>
187 mathias 24
 * @copyright  1997-2007 The PHP Group
94 jpm 25
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
187 mathias 26
 * @version    CVS: $Id$
94 jpm 27
 * @link       http://pear.php.net/package/DB
28
 */
29
 
30
/**
31
 * Obtain the DB_common class so it can be extended from
32
 */
33
require_once 'DB/common.php';
34
 
35
/**
36
 * The methods PEAR DB uses to interact with PHP's msql extension
37
 * for interacting with Mini SQL databases
38
 *
39
 * These methods overload the ones declared in DB_common.
40
 *
41
 * PHP's mSQL extension did weird things with NULL values prior to PHP
42
 * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
43
 * those versions.
44
 *
45
 * @category   Database
46
 * @package    DB
47
 * @author     Daniel Convissor <danielc@php.net>
187 mathias 48
 * @copyright  1997-2007 The PHP Group
94 jpm 49
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
187 mathias 50
 * @version    Release: 1.9.2
94 jpm 51
 * @link       http://pear.php.net/package/DB
52
 * @since      Class not functional until Release 1.7.0
53
 */
54
class DB_msql extends DB_common
55
{
56
    // {{{ properties
57
 
58
    /**
59
     * The DB driver type (mysql, oci8, odbc, etc.)
60
     * @var string
61
     */
62
    var $phptype = 'msql';
63
 
64
    /**
65
     * The database syntax variant to be used (db2, access, etc.), if any
66
     * @var string
67
     */
68
    var $dbsyntax = 'msql';
69
 
70
    /**
71
     * The capabilities of this DB implementation
72
     *
73
     * The 'new_link' element contains the PHP version that first provided
74
     * new_link support for this DBMS.  Contains false if it's unsupported.
75
     *
76
     * Meaning of the 'limit' element:
77
     *   + 'emulate' = emulate with fetch row by number
78
     *   + 'alter'   = alter the query
79
     *   + false     = skip rows
80
     *
81
     * @var array
82
     */
83
    var $features = array(
84
        'limit'         => 'emulate',
85
        'new_link'      => false,
86
        'numrows'       => true,
87
        'pconnect'      => true,
88
        'prepare'       => false,
89
        'ssl'           => false,
90
        'transactions'  => false,
91
    );
92
 
93
    /**
94
     * A mapping of native error codes to DB error codes
95
     * @var array
96
     */
97
    var $errorcode_map = array(
98
    );
99
 
100
    /**
101
     * The raw database connection created by PHP
102
     * @var resource
103
     */
104
    var $connection;
105
 
106
    /**
107
     * The DSN information for connecting to a database
108
     * @var array
109
     */
110
    var $dsn = array();
111
 
112
 
113
    /**
114
     * The query result resource created by PHP
115
     *
116
     * Used to make affectedRows() work.  Only contains the result for
117
     * data manipulation queries.  Contains false for other queries.
118
     *
119
     * @var resource
120
     * @access private
121
     */
122
    var $_result;
123
 
124
 
125
    // }}}
126
    // {{{ constructor
127
 
128
    /**
187 mathias 129
     * This constructor calls <kbd>parent::__construct()</kbd>
94 jpm 130
     *
131
     * @return void
132
     */
187 mathias 133
    function __construct()
94 jpm 134
    {
187 mathias 135
        parent::__construct();
94 jpm 136
    }
137
 
138
    // }}}
139
    // {{{ connect()
140
 
141
    /**
142
     * Connect to the database server, log in and open the database
143
     *
144
     * Don't call this method directly.  Use DB::connect() instead.
145
     *
146
     * Example of how to connect:
147
     * <code>
148
     * require_once 'DB.php';
149
     *
150
     * // $dsn = 'msql://hostname/dbname';  // use a TCP connection
151
     * $dsn = 'msql:///dbname';             // use a socket
152
     * $options = array(
153
     *     'portability' => DB_PORTABILITY_ALL,
154
     * );
155
     *
187 mathias 156
     * $db = DB::connect($dsn, $options);
94 jpm 157
     * if (PEAR::isError($db)) {
158
     *     die($db->getMessage());
159
     * }
160
     * </code>
161
     *
162
     * @param array $dsn         the data source name
163
     * @param bool  $persistent  should the connection be persistent?
164
     *
165
     * @return int  DB_OK on success. A DB_Error object on failure.
166
     */
167
    function connect($dsn, $persistent = false)
168
    {
169
        if (!PEAR::loadExtension('msql')) {
170
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
171
        }
172
 
173
        $this->dsn = $dsn;
174
        if ($dsn['dbsyntax']) {
175
            $this->dbsyntax = $dsn['dbsyntax'];
176
        }
177
 
178
        $params = array();
179
        if ($dsn['hostspec']) {
180
            $params[] = $dsn['port']
181
                        ? $dsn['hostspec'] . ',' . $dsn['port']
182
                        : $dsn['hostspec'];
183
        }
184
 
185
        $connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
186
 
187
        $ini = ini_get('track_errors');
188
        $php_errormsg = '';
189
        if ($ini) {
190
            $this->connection = @call_user_func_array($connect_function,
191
                                                      $params);
192
        } else {
187 mathias 193
            @ini_set('track_errors', 1);
94 jpm 194
            $this->connection = @call_user_func_array($connect_function,
195
                                                      $params);
187 mathias 196
            @ini_set('track_errors', $ini);
94 jpm 197
        }
198
 
199
        if (!$this->connection) {
200
            if (($err = @msql_error()) != '') {
201
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
202
                                         null, null, null,
203
                                         $err);
204
            } else {
205
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
206
                                         null, null, null,
207
                                         $php_errormsg);
208
            }
209
        }
210
 
211
        if (!@msql_select_db($dsn['database'], $this->connection)) {
212
            return $this->msqlRaiseError();
213
        }
214
        return DB_OK;
215
    }
216
 
217
    // }}}
218
    // {{{ disconnect()
219
 
220
    /**
221
     * Disconnects from the database server
222
     *
223
     * @return bool  TRUE on success, FALSE on failure
224
     */
225
    function disconnect()
226
    {
227
        $ret = @msql_close($this->connection);
228
        $this->connection = null;
229
        return $ret;
230
    }
231
 
232
    // }}}
233
    // {{{ simpleQuery()
234
 
235
    /**
236
     * Sends a query to the database server
237
     *
238
     * @param string  the SQL query string
239
     *
240
     * @return mixed  + a PHP result resrouce for successful SELECT queries
241
     *                + the DB_OK constant for other successful queries
242
     *                + a DB_Error object on failure
243
     */
244
    function simpleQuery($query)
245
    {
246
        $this->last_query = $query;
247
        $query = $this->modifyQuery($query);
248
        $result = @msql_query($query, $this->connection);
249
        if (!$result) {
250
            return $this->msqlRaiseError();
251
        }
252
        // Determine which queries that should return data, and which
253
        // should return an error code only.
187 mathias 254
        if ($this->_checkManip($query)) {
94 jpm 255
            $this->_result = $result;
256
            return DB_OK;
257
        } else {
258
            $this->_result = false;
259
            return $result;
260
        }
261
    }
262
 
263
 
264
    // }}}
265
    // {{{ nextResult()
266
 
267
    /**
268
     * Move the internal msql result pointer to the next available result
269
     *
270
     * @param a valid fbsql result resource
271
     *
272
     * @access public
273
     *
274
     * @return true if a result is available otherwise return false
275
     */
276
    function nextResult($result)
277
    {
278
        return false;
279
    }
280
 
281
    // }}}
282
    // {{{ fetchInto()
283
 
284
    /**
285
     * Places a row from the result set into the given array
286
     *
287
     * Formating of the array and the data therein are configurable.
288
     * See DB_result::fetchInto() for more information.
289
     *
290
     * This method is not meant to be called directly.  Use
291
     * DB_result::fetchInto() instead.  It can't be declared "protected"
292
     * because DB_result is a separate object.
293
     *
294
     * PHP's mSQL extension did weird things with NULL values prior to PHP
295
     * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
296
     * those versions.
297
     *
298
     * @param resource $result    the query result resource
299
     * @param array    $arr       the referenced array to put the data in
300
     * @param int      $fetchmode how the resulting array should be indexed
301
     * @param int      $rownum    the row number to fetch (0 = first row)
302
     *
303
     * @return mixed  DB_OK on success, NULL when the end of a result set is
304
     *                 reached or on failure
305
     *
306
     * @see DB_result::fetchInto()
307
     */
308
    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
309
    {
310
        if ($rownum !== null) {
311
            if (!@msql_data_seek($result, $rownum)) {
312
                return null;
313
            }
314
        }
315
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
316
            $arr = @msql_fetch_array($result, MSQL_ASSOC);
317
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
318
                $arr = array_change_key_case($arr, CASE_LOWER);
319
            }
320
        } else {
321
            $arr = @msql_fetch_row($result);
322
        }
323
        if (!$arr) {
324
            return null;
325
        }
326
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
327
            $this->_rtrimArrayValues($arr);
328
        }
329
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
330
            $this->_convertNullArrayValuesToEmpty($arr);
331
        }
332
        return DB_OK;
333
    }
334
 
335
    // }}}
336
    // {{{ freeResult()
337
 
338
    /**
339
     * Deletes the result set and frees the memory occupied by the result set
340
     *
341
     * This method is not meant to be called directly.  Use
342
     * DB_result::free() instead.  It can't be declared "protected"
343
     * because DB_result is a separate object.
344
     *
345
     * @param resource $result  PHP's query result resource
346
     *
347
     * @return bool  TRUE on success, FALSE if $result is invalid
348
     *
349
     * @see DB_result::free()
350
     */
351
    function freeResult($result)
352
    {
187 mathias 353
        return is_resource($result) ? msql_free_result($result) : false;
94 jpm 354
    }
355
 
356
    // }}}
357
    // {{{ numCols()
358
 
359
    /**
360
     * Gets the number of columns in a result set
361
     *
362
     * This method is not meant to be called directly.  Use
363
     * DB_result::numCols() instead.  It can't be declared "protected"
364
     * because DB_result is a separate object.
365
     *
366
     * @param resource $result  PHP's query result resource
367
     *
368
     * @return int  the number of columns.  A DB_Error object on failure.
369
     *
370
     * @see DB_result::numCols()
371
     */
372
    function numCols($result)
373
    {
374
        $cols = @msql_num_fields($result);
375
        if (!$cols) {
376
            return $this->msqlRaiseError();
377
        }
378
        return $cols;
379
    }
380
 
381
    // }}}
382
    // {{{ numRows()
383
 
384
    /**
385
     * Gets the number of rows in a result set
386
     *
387
     * This method is not meant to be called directly.  Use
388
     * DB_result::numRows() instead.  It can't be declared "protected"
389
     * because DB_result is a separate object.
390
     *
391
     * @param resource $result  PHP's query result resource
392
     *
393
     * @return int  the number of rows.  A DB_Error object on failure.
394
     *
395
     * @see DB_result::numRows()
396
     */
397
    function numRows($result)
398
    {
399
        $rows = @msql_num_rows($result);
400
        if ($rows === false) {
401
            return $this->msqlRaiseError();
402
        }
403
        return $rows;
404
    }
405
 
406
    // }}}
407
    // {{{ affected()
408
 
409
    /**
410
     * Determines the number of rows affected by a data maniuplation query
411
     *
412
     * 0 is returned for queries that don't manipulate data.
413
     *
414
     * @return int  the number of rows.  A DB_Error object on failure.
415
     */
416
    function affectedRows()
417
    {
418
        if (!$this->_result) {
419
            return 0;
420
        }
421
        return msql_affected_rows($this->_result);
422
    }
423
 
424
    // }}}
425
    // {{{ nextId()
426
 
427
    /**
428
     * Returns the next free id in a sequence
429
     *
430
     * @param string  $seq_name  name of the sequence
431
     * @param boolean $ondemand  when true, the seqence is automatically
432
     *                            created if it does not exist
433
     *
434
     * @return int  the next id number in the sequence.
435
     *               A DB_Error object on failure.
436
     *
437
     * @see DB_common::nextID(), DB_common::getSequenceName(),
438
     *      DB_msql::createSequence(), DB_msql::dropSequence()
439
     */
440
    function nextId($seq_name, $ondemand = true)
441
    {
442
        $seqname = $this->getSequenceName($seq_name);
443
        $repeat = false;
444
        do {
445
            $this->pushErrorHandling(PEAR_ERROR_RETURN);
187 mathias 446
            $result = $this->query("SELECT _seq FROM ${seqname}");
94 jpm 447
            $this->popErrorHandling();
448
            if ($ondemand && DB::isError($result) &&
449
                $result->getCode() == DB_ERROR_NOSUCHTABLE) {
450
                $repeat = true;
451
                $this->pushErrorHandling(PEAR_ERROR_RETURN);
452
                $result = $this->createSequence($seq_name);
453
                $this->popErrorHandling();
454
                if (DB::isError($result)) {
455
                    return $this->raiseError($result);
456
                }
457
            } else {
458
                $repeat = false;
459
            }
460
        } while ($repeat);
461
        if (DB::isError($result)) {
462
            return $this->raiseError($result);
463
        }
464
        $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
465
        $result->free();
466
        return $arr[0];
467
    }
468
 
469
    // }}}
470
    // {{{ createSequence()
471
 
472
    /**
473
     * Creates a new sequence
474
     *
475
     * Also creates a new table to associate the sequence with.  Uses
476
     * a separate table to ensure portability with other drivers.
477
     *
478
     * @param string $seq_name  name of the new sequence
479
     *
480
     * @return int  DB_OK on success.  A DB_Error object on failure.
481
     *
482
     * @see DB_common::createSequence(), DB_common::getSequenceName(),
483
     *      DB_msql::nextID(), DB_msql::dropSequence()
484
     */
485
    function createSequence($seq_name)
486
    {
487
        $seqname = $this->getSequenceName($seq_name);
488
        $res = $this->query('CREATE TABLE ' . $seqname
489
                            . ' (id INTEGER NOT NULL)');
490
        if (DB::isError($res)) {
491
            return $res;
492
        }
493
        $res = $this->query("CREATE SEQUENCE ON ${seqname}");
494
        return $res;
495
    }
496
 
497
    // }}}
498
    // {{{ dropSequence()
499
 
500
    /**
501
     * Deletes a sequence
502
     *
503
     * @param string $seq_name  name of the sequence to be deleted
504
     *
505
     * @return int  DB_OK on success.  A DB_Error object on failure.
506
     *
507
     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
508
     *      DB_msql::nextID(), DB_msql::createSequence()
509
     */
510
    function dropSequence($seq_name)
511
    {
512
        return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
513
    }
514
 
515
    // }}}
516
    // {{{ quoteIdentifier()
517
 
518
    /**
519
     * mSQL does not support delimited identifiers
520
     *
521
     * @param string $str  the identifier name to be quoted
522
     *
523
     * @return object  a DB_Error object
524
     *
525
     * @see DB_common::quoteIdentifier()
526
     * @since Method available since Release 1.7.0
527
     */
528
    function quoteIdentifier($str)
529
    {
530
        return $this->raiseError(DB_ERROR_UNSUPPORTED);
531
    }
532
 
533
    // }}}
187 mathias 534
    // {{{ quoteFloat()
535
 
536
    /**
537
     * Formats a float value for use within a query in a locale-independent
538
     * manner.
539
     *
540
     * @param float the float value to be quoted.
541
     * @return string the quoted string.
542
     * @see DB_common::quoteSmart()
543
     * @since Method available since release 1.7.8.
544
     */
545
    function quoteFloat($float) {
546
        return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
547
    }
548
 
549
    // }}}
94 jpm 550
    // {{{ escapeSimple()
551
 
552
    /**
553
     * Escapes a string according to the current DBMS's standards
554
     *
555
     * @param string $str  the string to be escaped
556
     *
557
     * @return string  the escaped string
558
     *
559
     * @see DB_common::quoteSmart()
560
     * @since Method available since Release 1.7.0
561
     */
562
    function escapeSimple($str)
563
    {
564
        return addslashes($str);
565
    }
566
 
567
    // }}}
568
    // {{{ msqlRaiseError()
569
 
570
    /**
571
     * Produces a DB_Error object regarding the current problem
572
     *
573
     * @param int $errno  if the error is being manually raised pass a
574
     *                     DB_ERROR* constant here.  If this isn't passed
575
     *                     the error information gathered from the DBMS.
576
     *
577
     * @return object  the DB_Error object
578
     *
579
     * @see DB_common::raiseError(),
580
     *      DB_msql::errorNative(), DB_msql::errorCode()
581
     */
582
    function msqlRaiseError($errno = null)
583
    {
584
        $native = $this->errorNative();
585
        if ($errno === null) {
586
            $errno = $this->errorCode($native);
587
        }
588
        return $this->raiseError($errno, null, null, null, $native);
589
    }
590
 
591
    // }}}
592
    // {{{ errorNative()
593
 
594
    /**
595
     * Gets the DBMS' native error message produced by the last query
596
     *
597
     * @return string  the DBMS' error message
598
     */
599
    function errorNative()
600
    {
601
        return @msql_error();
602
    }
603
 
604
    // }}}
605
    // {{{ errorCode()
606
 
607
    /**
608
     * Determines PEAR::DB error code from the database's text error message
609
     *
610
     * @param string $errormsg  the error message returned from the database
611
     *
612
     * @return integer  the error number from a DB_ERROR* constant
613
     */
614
    function errorCode($errormsg)
615
    {
616
        static $error_regexps;
187 mathias 617
 
618
        // PHP 5.2+ prepends the function name to $php_errormsg, so we need
619
        // this hack to work around it, per bug #9599.
620
        $errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg);
621
 
94 jpm 622
        if (!isset($error_regexps)) {
623
            $error_regexps = array(
624
                '/^Access to database denied/i'
625
                    => DB_ERROR_ACCESS_VIOLATION,
626
                '/^Bad index name/i'
627
                    => DB_ERROR_ALREADY_EXISTS,
628
                '/^Bad order field/i'
629
                    => DB_ERROR_SYNTAX,
630
                '/^Bad type for comparison/i'
631
                    => DB_ERROR_SYNTAX,
632
                '/^Can\'t perform LIKE on/i'
633
                    => DB_ERROR_SYNTAX,
634
                '/^Can\'t use TEXT fields in LIKE comparison/i'
635
                    => DB_ERROR_SYNTAX,
636
                '/^Couldn\'t create temporary table/i'
637
                    => DB_ERROR_CANNOT_CREATE,
638
                '/^Error creating table file/i'
639
                    => DB_ERROR_CANNOT_CREATE,
640
                '/^Field .* cannot be null$/i'
641
                    => DB_ERROR_CONSTRAINT_NOT_NULL,
642
                '/^Index (field|condition) .* cannot be null$/i'
643
                    => DB_ERROR_SYNTAX,
644
                '/^Invalid date format/i'
645
                    => DB_ERROR_INVALID_DATE,
646
                '/^Invalid time format/i'
647
                    => DB_ERROR_INVALID,
648
                '/^Literal value for .* is wrong type$/i'
649
                    => DB_ERROR_INVALID_NUMBER,
650
                '/^No Database Selected/i'
651
                    => DB_ERROR_NODBSELECTED,
652
                '/^No value specified for field/i'
653
                    => DB_ERROR_VALUE_COUNT_ON_ROW,
654
                '/^Non unique value for unique index/i'
655
                    => DB_ERROR_CONSTRAINT,
656
                '/^Out of memory for temporary table/i'
657
                    => DB_ERROR_CANNOT_CREATE,
658
                '/^Permission denied/i'
659
                    => DB_ERROR_ACCESS_VIOLATION,
660
                '/^Reference to un-selected table/i'
661
                    => DB_ERROR_SYNTAX,
662
                '/^syntax error/i'
663
                    => DB_ERROR_SYNTAX,
664
                '/^Table .* exists$/i'
665
                    => DB_ERROR_ALREADY_EXISTS,
666
                '/^Unknown database/i'
667
                    => DB_ERROR_NOSUCHDB,
668
                '/^Unknown field/i'
669
                    => DB_ERROR_NOSUCHFIELD,
670
                '/^Unknown (index|system variable)/i'
671
                    => DB_ERROR_NOT_FOUND,
672
                '/^Unknown table/i'
673
                    => DB_ERROR_NOSUCHTABLE,
674
                '/^Unqualified field/i'
675
                    => DB_ERROR_SYNTAX,
676
            );
677
        }
678
 
679
        foreach ($error_regexps as $regexp => $code) {
680
            if (preg_match($regexp, $errormsg)) {
681
                return $code;
682
            }
683
        }
684
        return DB_ERROR;
685
    }
686
 
687
    // }}}
688
    // {{{ tableInfo()
689
 
690
    /**
691
     * Returns information about a table or a result set
692
     *
693
     * @param object|string  $result  DB_result object from a query or a
694
     *                                 string containing the name of a table.
695
     *                                 While this also accepts a query result
696
     *                                 resource identifier, this behavior is
697
     *                                 deprecated.
698
     * @param int            $mode    a valid tableInfo mode
699
     *
700
     * @return array  an associative array with the information requested.
701
     *                 A DB_Error object on failure.
702
     *
703
     * @see DB_common::setOption()
704
     */
705
    function tableInfo($result, $mode = null)
706
    {
707
        if (is_string($result)) {
708
            /*
709
             * Probably received a table name.
710
             * Create a result resource identifier.
711
             */
712
            $id = @msql_query("SELECT * FROM $result",
713
                              $this->connection);
714
            $got_string = true;
715
        } elseif (isset($result->result)) {
716
            /*
717
             * Probably received a result object.
718
             * Extract the result resource identifier.
719
             */
720
            $id = $result->result;
721
            $got_string = false;
722
        } else {
723
            /*
724
             * Probably received a result resource identifier.
725
             * Copy it.
726
             * Deprecated.  Here for compatibility only.
727
             */
728
            $id = $result;
729
            $got_string = false;
730
        }
731
 
732
        if (!is_resource($id)) {
733
            return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
734
        }
735
 
736
        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
737
            $case_func = 'strtolower';
738
        } else {
739
            $case_func = 'strval';
740
        }
741
 
742
        $count = @msql_num_fields($id);
743
        $res   = array();
744
 
745
        if ($mode) {
746
            $res['num_fields'] = $count;
747
        }
748
 
749
        for ($i = 0; $i < $count; $i++) {
750
            $tmp = @msql_fetch_field($id);
751
 
752
            $flags = '';
753
            if ($tmp->not_null) {
754
                $flags .= 'not_null ';
755
            }
756
            if ($tmp->unique) {
757
                $flags .= 'unique_key ';
758
            }
759
            $flags = trim($flags);
760
 
761
            $res[$i] = array(
762
                'table' => $case_func($tmp->table),
763
                'name'  => $case_func($tmp->name),
764
                'type'  => $tmp->type,
765
                'len'   => msql_field_len($id, $i),
766
                'flags' => $flags,
767
            );
768
 
769
            if ($mode & DB_TABLEINFO_ORDER) {
770
                $res['order'][$res[$i]['name']] = $i;
771
            }
772
            if ($mode & DB_TABLEINFO_ORDERTABLE) {
773
                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
774
            }
775
        }
776
 
777
        // free the result only if we were called on a table
778
        if ($got_string) {
779
            @msql_free_result($id);
780
        }
781
        return $res;
782
    }
783
 
784
    // }}}
785
    // {{{ getSpecialQuery()
786
 
787
    /**
788
     * Obtain a list of a given type of objects
789
     *
790
     * @param string $type  the kind of objects you want to retrieve
791
     *
792
     * @return array  the array containing the list of objects requested
793
     *
794
     * @access protected
795
     * @see DB_common::getListOf()
796
     */
797
    function getSpecialQuery($type)
798
    {
799
        switch ($type) {
800
            case 'databases':
801
                $id = @msql_list_dbs($this->connection);
802
                break;
803
            case 'tables':
804
                $id = @msql_list_tables($this->dsn['database'],
805
                                        $this->connection);
806
                break;
807
            default:
808
                return null;
809
        }
810
        if (!$id) {
811
            return $this->msqlRaiseError();
812
        }
813
        $out = array();
814
        while ($row = @msql_fetch_row($id)) {
815
            $out[] = $row[0];
816
        }
817
        return $out;
818
    }
819
 
820
    // }}}
821
 
822
}
823
 
824
/*
825
 * Local variables:
826
 * tab-width: 4
827
 * c-basic-offset: 4
828
 * End:
829
 */
830
 
831
?>