source: branches/feature-module-update/data/module/DB/odbc.php @ 15532

Revision 15532, 26.3 KB checked in by nanasess, 14 years ago (diff)

svn:mime-type 修正

  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5/**
6 * The PEAR DB driver for PHP's odbc extension
7 * for interacting with databases via ODBC connections
8 *
9 * PHP versions 4 and 5
10 *
11 * LICENSE: This source file is subject to version 3.0 of the PHP license
12 * that is available through the world-wide-web at the following URI:
13 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
14 * the PHP License and are unable to obtain it through the web, please
15 * send a note to license@php.net so we can mail you a copy immediately.
16 *
17 * @category   Database
18 * @package    DB
19 * @author     Stig Bakken <ssb@php.net>
20 * @author     Daniel Convissor <danielc@php.net>
21 * @copyright  1997-2005 The PHP Group
22 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
23 * @version    CVS: $Id$
24 * @link       http://pear.php.net/package/DB
25 */
26
27/**
28 * Obtain the DB_common class so it can be extended from
29 */
30require_once 'DB/common.php';
31
32/**
33 * The methods PEAR DB uses to interact with PHP's odbc extension
34 * for interacting with databases via ODBC connections
35 *
36 * These methods overload the ones declared in DB_common.
37 *
38 * More info on ODBC errors could be found here:
39 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp
40 *
41 * @category   Database
42 * @package    DB
43 * @author     Stig Bakken <ssb@php.net>
44 * @author     Daniel Convissor <danielc@php.net>
45 * @copyright  1997-2005 The PHP Group
46 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
47 * @version    Release: @package_version@
48 * @link       http://pear.php.net/package/DB
49 */
50class DB_odbc extends DB_common
51{
52    // {{{ properties
53
54    /**
55     * The DB driver type (mysql, oci8, odbc, etc.)
56     * @var string
57     */
58    var $phptype = 'odbc';
59
60    /**
61     * The database syntax variant to be used (db2, access, etc.), if any
62     * @var string
63     */
64    var $dbsyntax = 'sql92';
65
66    /**
67     * The capabilities of this DB implementation
68     *
69     * The 'new_link' element contains the PHP version that first provided
70     * new_link support for this DBMS.  Contains false if it's unsupported.
71     *
72     * Meaning of the 'limit' element:
73     *   + 'emulate' = emulate with fetch row by number
74     *   + 'alter'   = alter the query
75     *   + false     = skip rows
76     *
77     * NOTE: The feature set of the following drivers are different than
78     * the default:
79     *   + solid: 'transactions' = true
80     *   + navision: 'limit' = false
81     *
82     * @var array
83     */
84    var $features = array(
85        'limit'         => 'emulate',
86        'new_link'      => false,
87        'numrows'       => true,
88        'pconnect'      => true,
89        'prepare'       => false,
90        'ssl'           => false,
91        'transactions'  => false,
92    );
93
94    /**
95     * A mapping of native error codes to DB error codes
96     * @var array
97     */
98    var $errorcode_map = array(
99        '01004' => DB_ERROR_TRUNCATED,
100        '07001' => DB_ERROR_MISMATCH,
101        '21S01' => DB_ERROR_VALUE_COUNT_ON_ROW,
102        '21S02' => DB_ERROR_MISMATCH,
103        '22001' => DB_ERROR_INVALID,
104        '22003' => DB_ERROR_INVALID_NUMBER,
105        '22005' => DB_ERROR_INVALID_NUMBER,
106        '22008' => DB_ERROR_INVALID_DATE,
107        '22012' => DB_ERROR_DIVZERO,
108        '23000' => DB_ERROR_CONSTRAINT,
109        '23502' => DB_ERROR_CONSTRAINT_NOT_NULL,
110        '23503' => DB_ERROR_CONSTRAINT,
111        '23504' => DB_ERROR_CONSTRAINT,
112        '23505' => DB_ERROR_CONSTRAINT,
113        '24000' => DB_ERROR_INVALID,
114        '34000' => DB_ERROR_INVALID,
115        '37000' => DB_ERROR_SYNTAX,
116        '42000' => DB_ERROR_SYNTAX,
117        '42601' => DB_ERROR_SYNTAX,
118        'IM001' => DB_ERROR_UNSUPPORTED,
119        'S0000' => DB_ERROR_NOSUCHTABLE,
120        'S0001' => DB_ERROR_ALREADY_EXISTS,
121        'S0002' => DB_ERROR_NOSUCHTABLE,
122        'S0011' => DB_ERROR_ALREADY_EXISTS,
123        'S0012' => DB_ERROR_NOT_FOUND,
124        'S0021' => DB_ERROR_ALREADY_EXISTS,
125        'S0022' => DB_ERROR_NOSUCHFIELD,
126        'S1009' => DB_ERROR_INVALID,
127        'S1090' => DB_ERROR_INVALID,
128        'S1C00' => DB_ERROR_NOT_CAPABLE,
129    );
130
131    /**
132     * The raw database connection created by PHP
133     * @var resource
134     */
135    var $connection;
136
137    /**
138     * The DSN information for connecting to a database
139     * @var array
140     */
141    var $dsn = array();
142
143
144    /**
145     * The number of rows affected by a data manipulation query
146     * @var integer
147     * @access private
148     */
149    var $affected = 0;
150
151
152    // }}}
153    // {{{ constructor
154
155    /**
156     * This constructor calls <kbd>$this->DB_common()</kbd>
157     *
158     * @return void
159     */
160    function DB_odbc()
161    {
162        $this->DB_common();
163    }
164
165    // }}}
166    // {{{ connect()
167
168    /**
169     * Connect to the database server, log in and open the database
170     *
171     * Don't call this method directly.  Use DB::connect() instead.
172     *
173     * PEAR DB's odbc driver supports the following extra DSN options:
174     *   + cursor  The type of cursor to be used for this connection.
175     *
176     * @param array $dsn         the data source name
177     * @param bool  $persistent  should the connection be persistent?
178     *
179     * @return int  DB_OK on success. A DB_Error object on failure.
180     */
181    function connect($dsn, $persistent = false)
182    {
183        if (!PEAR::loadExtension('odbc')) {
184            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
185        }
186
187        $this->dsn = $dsn;
188        if ($dsn['dbsyntax']) {
189            $this->dbsyntax = $dsn['dbsyntax'];
190        }
191        switch ($this->dbsyntax) {
192            case 'access':
193            case 'db2':
194            case 'solid':
195                $this->features['transactions'] = true;
196                break;
197            case 'navision':
198                $this->features['limit'] = false;
199        }
200
201        /*
202         * This is hear for backwards compatibility. Should have been using
203         * 'database' all along, but prior to 1.6.0RC3 'hostspec' was used.
204         */
205        if ($dsn['database']) {
206            $odbcdsn = $dsn['database'];
207        } elseif ($dsn['hostspec']) {
208            $odbcdsn = $dsn['hostspec'];
209        } else {
210            $odbcdsn = 'localhost';
211        }
212
213        $connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
214
215        if (empty($dsn['cursor'])) {
216            $this->connection = @$connect_function($odbcdsn, $dsn['username'],
217                                                   $dsn['password']);
218        } else {
219            $this->connection = @$connect_function($odbcdsn, $dsn['username'],
220                                                   $dsn['password'],
221                                                   $dsn['cursor']);
222        }
223
224        if (!is_resource($this->connection)) {
225            return $this->raiseError(DB_ERROR_CONNECT_FAILED,
226                                     null, null, null,
227                                     $this->errorNative());
228        }
229        return DB_OK;
230    }
231
232    // }}}
233    // {{{ disconnect()
234
235    /**
236     * Disconnects from the database server
237     *
238     * @return bool  TRUE on success, FALSE on failure
239     */
240    function disconnect()
241    {
242        $err = @odbc_close($this->connection);
243        $this->connection = null;
244        return $err;
245    }
246
247    // }}}
248    // {{{ simpleQuery()
249
250    /**
251     * Sends a query to the database server
252     *
253     * @param string  the SQL query string
254     *
255     * @return mixed  + a PHP result resrouce for successful SELECT queries
256     *                + the DB_OK constant for other successful queries
257     *                + a DB_Error object on failure
258     */
259    function simpleQuery($query)
260    {
261        $this->last_query = $query;
262        $query = $this->modifyQuery($query);
263        $result = @odbc_exec($this->connection, $query);
264        if (!$result) {
265            return $this->odbcRaiseError(); // XXX ERRORMSG
266        }
267        // Determine which queries that should return data, and which
268        // should return an error code only.
269        if (DB::isManip($query)) {
270            $this->affected = $result; // For affectedRows()
271            return DB_OK;
272        }
273        $this->affected = 0;
274        return $result;
275    }
276
277    // }}}
278    // {{{ nextResult()
279
280    /**
281     * Move the internal odbc result pointer to the next available result
282     *
283     * @param a valid fbsql result resource
284     *
285     * @access public
286     *
287     * @return true if a result is available otherwise return false
288     */
289    function nextResult($result)
290    {
291        return @odbc_next_result($result);
292    }
293
294    // }}}
295    // {{{ fetchInto()
296
297    /**
298     * Places a row from the result set into the given array
299     *
300     * Formating of the array and the data therein are configurable.
301     * See DB_result::fetchInto() for more information.
302     *
303     * This method is not meant to be called directly.  Use
304     * DB_result::fetchInto() instead.  It can't be declared "protected"
305     * because DB_result is a separate object.
306     *
307     * @param resource $result    the query result resource
308     * @param array    $arr       the referenced array to put the data in
309     * @param int      $fetchmode how the resulting array should be indexed
310     * @param int      $rownum    the row number to fetch (0 = first row)
311     *
312     * @return mixed  DB_OK on success, NULL when the end of a result set is
313     *                 reached or on failure
314     *
315     * @see DB_result::fetchInto()
316     */
317    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
318    {
319        $arr = array();
320        if ($rownum !== null) {
321            $rownum++; // ODBC first row is 1
322            if (version_compare(phpversion(), '4.2.0', 'ge')) {
323                $cols = @odbc_fetch_into($result, $arr, $rownum);
324            } else {
325                $cols = @odbc_fetch_into($result, $rownum, $arr);
326            }
327        } else {
328            $cols = @odbc_fetch_into($result, $arr);
329        }
330        if (!$cols) {
331            return null;
332        }
333        if ($fetchmode !== DB_FETCHMODE_ORDERED) {
334            for ($i = 0; $i < count($arr); $i++) {
335                $colName = @odbc_field_name($result, $i+1);
336                $a[$colName] = $arr[$i];
337            }
338            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
339                $a = array_change_key_case($a, CASE_LOWER);
340            }
341            $arr = $a;
342        }
343        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
344            $this->_rtrimArrayValues($arr);
345        }
346        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
347            $this->_convertNullArrayValuesToEmpty($arr);
348        }
349        return DB_OK;
350    }
351
352    // }}}
353    // {{{ freeResult()
354
355    /**
356     * Deletes the result set and frees the memory occupied by the result set
357     *
358     * This method is not meant to be called directly.  Use
359     * DB_result::free() instead.  It can't be declared "protected"
360     * because DB_result is a separate object.
361     *
362     * @param resource $result  PHP's query result resource
363     *
364     * @return bool  TRUE on success, FALSE if $result is invalid
365     *
366     * @see DB_result::free()
367     */
368    function freeResult($result)
369    {
370        return @odbc_free_result($result);
371    }
372
373    // }}}
374    // {{{ numCols()
375
376    /**
377     * Gets the number of columns in a result set
378     *
379     * This method is not meant to be called directly.  Use
380     * DB_result::numCols() instead.  It can't be declared "protected"
381     * because DB_result is a separate object.
382     *
383     * @param resource $result  PHP's query result resource
384     *
385     * @return int  the number of columns.  A DB_Error object on failure.
386     *
387     * @see DB_result::numCols()
388     */
389    function numCols($result)
390    {
391        $cols = @odbc_num_fields($result);
392        if (!$cols) {
393            return $this->odbcRaiseError();
394        }
395        return $cols;
396    }
397
398    // }}}
399    // {{{ affectedRows()
400
401    /**
402     * Determines the number of rows affected by a data maniuplation query
403     *
404     * 0 is returned for queries that don't manipulate data.
405     *
406     * @return int  the number of rows.  A DB_Error object on failure.
407     */
408    function affectedRows()
409    {
410        if (empty($this->affected)) {  // In case of SELECT stms
411            return 0;
412        }
413        $nrows = @odbc_num_rows($this->affected);
414        if ($nrows == -1) {
415            return $this->odbcRaiseError();
416        }
417        return $nrows;
418    }
419
420    // }}}
421    // {{{ numRows()
422
423    /**
424     * Gets the number of rows in a result set
425     *
426     * Not all ODBC drivers support this functionality.  If they don't
427     * a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
428     *
429     * This method is not meant to be called directly.  Use
430     * DB_result::numRows() instead.  It can't be declared "protected"
431     * because DB_result is a separate object.
432     *
433     * @param resource $result  PHP's query result resource
434     *
435     * @return int  the number of rows.  A DB_Error object on failure.
436     *
437     * @see DB_result::numRows()
438     */
439    function numRows($result)
440    {
441        $nrows = @odbc_num_rows($result);
442        if ($nrows == -1) {
443            return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
444        }
445        if ($nrows === false) {
446            return $this->odbcRaiseError();
447        }
448        return $nrows;
449    }
450
451    // }}}
452    // {{{ quoteIdentifier()
453
454    /**
455     * Quotes a string so it can be safely used as a table or column name
456     *
457     * Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
458     * "Use ANSI quoted identifiers" when setting up the ODBC data source.
459     *
460     * @param string $str  identifier name to be quoted
461     *
462     * @return string  quoted identifier string
463     *
464     * @see DB_common::quoteIdentifier()
465     * @since Method available since Release 1.6.0
466     */
467    function quoteIdentifier($str)
468    {
469        switch ($this->dsn['dbsyntax']) {
470            case 'access':
471                return '[' . $str . ']';
472            case 'mssql':
473            case 'sybase':
474                return '[' . str_replace(']', ']]', $str) . ']';
475            case 'mysql':
476            case 'mysqli':
477                return '`' . $str . '`';
478            default:
479                return '"' . str_replace('"', '""', $str) . '"';
480        }
481    }
482
483    // }}}
484    // {{{ quote()
485
486    /**
487     * @deprecated  Deprecated in release 1.6.0
488     * @internal
489     */
490    function quote($str)
491    {
492        return $this->quoteSmart($str);
493    }
494
495    // }}}
496    // {{{ nextId()
497
498    /**
499     * Returns the next free id in a sequence
500     *
501     * @param string  $seq_name  name of the sequence
502     * @param boolean $ondemand  when true, the seqence is automatically
503     *                            created if it does not exist
504     *
505     * @return int  the next id number in the sequence.
506     *               A DB_Error object on failure.
507     *
508     * @see DB_common::nextID(), DB_common::getSequenceName(),
509     *      DB_odbc::createSequence(), DB_odbc::dropSequence()
510     */
511    function nextId($seq_name, $ondemand = true)
512    {
513        $seqname = $this->getSequenceName($seq_name);
514        $repeat = 0;
515        do {
516            $this->pushErrorHandling(PEAR_ERROR_RETURN);
517            $result = $this->query("update ${seqname} set id = id + 1");
518            $this->popErrorHandling();
519            if ($ondemand && DB::isError($result) &&
520                $result->getCode() == DB_ERROR_NOSUCHTABLE) {
521                $repeat = 1;
522                $this->pushErrorHandling(PEAR_ERROR_RETURN);
523                $result = $this->createSequence($seq_name);
524                $this->popErrorHandling();
525                if (DB::isError($result)) {
526                    return $this->raiseError($result);
527                }
528                $result = $this->query("insert into ${seqname} (id) values(0)");
529            } else {
530                $repeat = 0;
531            }
532        } while ($repeat);
533
534        if (DB::isError($result)) {
535            return $this->raiseError($result);
536        }
537
538        $result = $this->query("select id from ${seqname}");
539        if (DB::isError($result)) {
540            return $result;
541        }
542
543        $row = $result->fetchRow(DB_FETCHMODE_ORDERED);
544        if (DB::isError($row || !$row)) {
545            return $row;
546        }
547
548        return $row[0];
549    }
550
551    /**
552     * Creates a new sequence
553     *
554     * @param string $seq_name  name of the new sequence
555     *
556     * @return int  DB_OK on success.  A DB_Error object on failure.
557     *
558     * @see DB_common::createSequence(), DB_common::getSequenceName(),
559     *      DB_odbc::nextID(), DB_odbc::dropSequence()
560     */
561    function createSequence($seq_name)
562    {
563        return $this->query('CREATE TABLE '
564                            . $this->getSequenceName($seq_name)
565                            . ' (id integer NOT NULL,'
566                            . ' PRIMARY KEY(id))');
567    }
568
569    // }}}
570    // {{{ dropSequence()
571
572    /**
573     * Deletes a sequence
574     *
575     * @param string $seq_name  name of the sequence to be deleted
576     *
577     * @return int  DB_OK on success.  A DB_Error object on failure.
578     *
579     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
580     *      DB_odbc::nextID(), DB_odbc::createSequence()
581     */
582    function dropSequence($seq_name)
583    {
584        return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
585    }
586
587    // }}}
588    // {{{ autoCommit()
589
590    /**
591     * Enables or disables automatic commits
592     *
593     * @param bool $onoff  true turns it on, false turns it off
594     *
595     * @return int  DB_OK on success.  A DB_Error object if the driver
596     *               doesn't support auto-committing transactions.
597     */
598    function autoCommit($onoff = false)
599    {
600        if (!@odbc_autocommit($this->connection, $onoff)) {
601            return $this->odbcRaiseError();
602        }
603        return DB_OK;
604    }
605
606    // }}}
607    // {{{ commit()
608
609    /**
610     * Commits the current transaction
611     *
612     * @return int  DB_OK on success.  A DB_Error object on failure.
613     */
614    function commit()
615    {
616        if (!@odbc_commit($this->connection)) {
617            return $this->odbcRaiseError();
618        }
619        return DB_OK;
620    }
621
622    // }}}
623    // {{{ rollback()
624
625    /**
626     * Reverts the current transaction
627     *
628     * @return int  DB_OK on success.  A DB_Error object on failure.
629     */
630    function rollback()
631    {
632        if (!@odbc_rollback($this->connection)) {
633            return $this->odbcRaiseError();
634        }
635        return DB_OK;
636    }
637
638    // }}}
639    // {{{ odbcRaiseError()
640
641    /**
642     * Produces a DB_Error object regarding the current problem
643     *
644     * @param int $errno  if the error is being manually raised pass a
645     *                     DB_ERROR* constant here.  If this isn't passed
646     *                     the error information gathered from the DBMS.
647     *
648     * @return object  the DB_Error object
649     *
650     * @see DB_common::raiseError(),
651     *      DB_odbc::errorNative(), DB_common::errorCode()
652     */
653    function odbcRaiseError($errno = null)
654    {
655        if ($errno === null) {
656            switch ($this->dbsyntax) {
657                case 'access':
658                    if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
659                        $this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD;
660                    } else {
661                        // Doing this in case mode changes during runtime.
662                        $this->errorcode_map['07001'] = DB_ERROR_MISMATCH;
663                    }
664
665                    $native_code = odbc_error($this->connection);
666
667                    // S1000 is for "General Error."  Let's be more specific.
668                    if ($native_code == 'S1000') {
669                        $errormsg = odbc_errormsg($this->connection);
670                        static $error_regexps;
671                        if (!isset($error_regexps)) {
672                            $error_regexps = array(
673                                '/includes related records.$/i'  => DB_ERROR_CONSTRAINT,
674                                '/cannot contain a Null value/i' => DB_ERROR_CONSTRAINT_NOT_NULL,
675                            );
676                        }
677                        foreach ($error_regexps as $regexp => $code) {
678                            if (preg_match($regexp, $errormsg)) {
679                                return $this->raiseError($code,
680                                        null, null, null,
681                                        $native_code . ' ' . $errormsg);
682                            }
683                        }
684                        $errno = DB_ERROR;
685                    } else {
686                        $errno = $this->errorCode($native_code);
687                    }
688                    break;
689                default:
690                    $errno = $this->errorCode(odbc_error($this->connection));
691            }
692        }
693        return $this->raiseError($errno, null, null, null,
694                                 $this->errorNative());
695    }
696
697    // }}}
698    // {{{ errorNative()
699
700    /**
701     * Gets the DBMS' native error code and message produced by the last query
702     *
703     * @return string  the DBMS' error code and message
704     */
705    function errorNative()
706    {
707        if (!is_resource($this->connection)) {
708            return @odbc_error() . ' ' . @odbc_errormsg();
709        }
710        return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
711    }
712
713    // }}}
714    // {{{ tableInfo()
715
716    /**
717     * Returns information about a table or a result set
718     *
719     * @param object|string  $result  DB_result object from a query or a
720     *                                 string containing the name of a table.
721     *                                 While this also accepts a query result
722     *                                 resource identifier, this behavior is
723     *                                 deprecated.
724     * @param int            $mode    a valid tableInfo mode
725     *
726     * @return array  an associative array with the information requested.
727     *                 A DB_Error object on failure.
728     *
729     * @see DB_common::tableInfo()
730     * @since Method available since Release 1.7.0
731     */
732    function tableInfo($result, $mode = null)
733    {
734        if (is_string($result)) {
735            /*
736             * Probably received a table name.
737             * Create a result resource identifier.
738             */
739            $id = @odbc_exec($this->connection, "SELECT * FROM $result");
740            if (!$id) {
741                return $this->odbcRaiseError();
742            }
743            $got_string = true;
744        } elseif (isset($result->result)) {
745            /*
746             * Probably received a result object.
747             * Extract the result resource identifier.
748             */
749            $id = $result->result;
750            $got_string = false;
751        } else {
752            /*
753             * Probably received a result resource identifier.
754             * Copy it.
755             * Deprecated.  Here for compatibility only.
756             */
757            $id = $result;
758            $got_string = false;
759        }
760
761        if (!is_resource($id)) {
762            return $this->odbcRaiseError(DB_ERROR_NEED_MORE_DATA);
763        }
764
765        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
766            $case_func = 'strtolower';
767        } else {
768            $case_func = 'strval';
769        }
770
771        $count = @odbc_num_fields($id);
772        $res   = array();
773
774        if ($mode) {
775            $res['num_fields'] = $count;
776        }
777
778        for ($i = 0; $i < $count; $i++) {
779            $col = $i + 1;
780            $res[$i] = array(
781                'table' => $got_string ? $case_func($result) : '',
782                'name'  => $case_func(@odbc_field_name($id, $col)),
783                'type'  => @odbc_field_type($id, $col),
784                'len'   => @odbc_field_len($id, $col),
785                'flags' => '',
786            );
787            if ($mode & DB_TABLEINFO_ORDER) {
788                $res['order'][$res[$i]['name']] = $i;
789            }
790            if ($mode & DB_TABLEINFO_ORDERTABLE) {
791                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
792            }
793        }
794
795        // free the result only if we were called on a table
796        if ($got_string) {
797            @odbc_free_result($id);
798        }
799        return $res;
800    }
801
802    // }}}
803    // {{{ getSpecialQuery()
804
805    /**
806     * Obtains the query string needed for listing a given type of objects
807     *
808     * Thanks to symbol1@gmail.com and Philippe.Jausions@11abacus.com.
809     *
810     * @param string $type  the kind of objects you want to retrieve
811     *
812     * @return string  the list of objects requested
813     *
814     * @access protected
815     * @see DB_common::getListOf()
816     * @since Method available since Release 1.7.0
817     */
818    function getSpecialQuery($type)
819    {
820        switch ($type) {
821            case 'databases':
822                if (!function_exists('odbc_data_source')) {
823                    return null;
824                }
825                $res = @odbc_data_source($this->connection, SQL_FETCH_FIRST);
826                if (is_array($res)) {
827                    $out = array($res['server']);
828                    while($res = @odbc_data_source($this->connection,
829                                                   SQL_FETCH_NEXT))
830                    {
831                        $out[] = $res['server'];
832                    }
833                    return $out;
834                } else {
835                    return $this->odbcRaiseError();
836                }
837                break;
838            case 'tables':
839            case 'schema.tables':
840                $keep = 'TABLE';
841                break;
842            case 'views':
843                $keep = 'VIEW';
844                break;
845            default:
846                return null;
847        }
848
849        /*
850         * Removing non-conforming items in the while loop rather than
851         * in the odbc_tables() call because some backends choke on this:
852         *     odbc_tables($this->connection, '', '', '', 'TABLE')
853         */
854        $res  = @odbc_tables($this->connection);
855        if (!$res) {
856            return $this->odbcRaiseError();
857        }
858        $out = array();
859        while ($row = odbc_fetch_array($res)) {
860            if ($row['TABLE_TYPE'] != $keep) {
861                continue;
862            }
863            if ($type == 'schema.tables') {
864                $out[] = $row['TABLE_SCHEM'] . '.' . $row['TABLE_NAME'];
865            } else {
866                $out[] = $row['TABLE_NAME'];
867            }
868        }
869        return $out;
870    }
871
872    // }}}
873
874}
875
876/*
877 * Local variables:
878 * tab-width: 4
879 * c-basic-offset: 4
880 * End:
881 */
882
883?>
Note: See TracBrowser for help on using the repository browser.