Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

<?php
/**
 * PDO MySQL driver
 *
 * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
 *
 * @package ADOdb
 * @link https://adodb.org Project's web site and documentation
 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
 *
 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
 * any later version. This means you can use it in proprietary products.
 * See the LICENSE.md file distributed with this source code for details.
 * @license BSD-3-Clause
 * @license LGPL-2.1-or-later
 *
 * @copyright 2000-2013 John Lim
 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
 */

class ADODB_pdo_mysql extends ADODB_pdo {

        var $metaTablesSQL = "SELECT
                        TABLE_NAME,
                        CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
                FROM INFORMATION_SCHEMA.TABLES
                WHERE TABLE_SCHEMA=";
        var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
        var $sysDate = 'CURDATE()';
        var $sysTimeStamp = 'NOW()';
        var $hasGenID = true;
        var $_genIDSQL = "UPDATE %s SET id=LAST_INSERT_ID(id+1);";
        var $_genSeqSQL = "CREATE TABLE  if NOT EXISTS %s (id int not null)";
        var $_genSeqCountSQL = "SELECT count(*) FROM %s";
        var $_genSeq2SQL = "INSERT INTO %s VALUES (%s)";
        var $_dropSeqSQL = "drop table %s";
        var $fmtTimeStamp = "'Y-m-d H:i:s'";
        var $nameQuote = '`';

        function _init($parentDriver)
        {
                $parentDriver->hasTransactions = false;
                #$parentDriver->_bindInputArray = false;
                $parentDriver->hasInsertID = true;
                $parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
        }

        // dayFraction is a day in floating point
        function OffsetDate($dayFraction, $date=false)
        {
                if (!$date) {
                        $date = $this->sysDate;
                }

                $fraction = $dayFraction * 24 * 3600;
                return $date . ' + INTERVAL ' . $fraction . ' SECOND';
//              return "from_unixtime(unix_timestamp($date)+$fraction)";
        }

        /**
         * Get a list of indexes on the specified table.
         *
         * @param string $table The name of the table to get indexes for.
         * @param bool $primary (Optional) Whether or not to include the primary key.
         * @param bool $owner (Optional) Unused.
         *
         * @return array|bool An array of the indexes, or false if the query to get the indexes failed.
         */
        function metaIndexes($table, $primary = false, $owner = false)
        {
                // save old fetch mode
                global $ADODB_FETCH_MODE;

                $false = false;
                $save = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== FALSE) {
                        $savem = $this->setFetchMode(FALSE);
                }

                // get index details
                $rs = $this->execute(sprintf('SHOW INDEXES FROM %s',$table));

                // restore fetchmode
                if (isset($savem)) {
                        $this->setFetchMode($savem);
                }
                $ADODB_FETCH_MODE = $save;

                if (!is_object($rs)) {
                        return $false;
                }

                $indexes = array ();

                // parse index data into array
                while ($row = $rs->fetchRow()) {
                        if ($primary == FALSE AND $row[2] == 'PRIMARY') {
                                continue;
                        }

                        if (!isset($indexes[$row[2]])) {
                                $indexes[$row[2]] = array(
                                        'unique' => ($row[1] == 0),
                                        'columns' => array()
                                );
                        }

                        $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
                }

                // sort columns by order in the index
                foreach ( array_keys ($indexes) as $index )
                {
                        ksort ($indexes[$index]['columns']);
                }

                return $indexes;
        }

        function Concat()
        {
                $s = '';
                $arr = func_get_args();

                // suggestion by andrew005#mnogo.ru
                $s = implode(',', $arr);
                if (strlen($s) > 0) {
                        return "CONCAT($s)";
                }
                return '';
        }

        function ServerInfo()
        {
                $arr['description'] = ADOConnection::GetOne('select version()');
                $arr['version'] = ADOConnection::_findvers($arr['description']);
                return $arr;
        }

        function MetaTables($ttype=false, $showSchema=false, $mask=false)
        {
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
                        $this->metaTablesSQL .= $this->qstr($showSchema);
                } else {
                        $this->metaTablesSQL .= 'schema()';
                }

                if ($mask) {
                        $mask = $this->qstr($mask);
                        $this->metaTablesSQL .= " like $mask";
                }
                $ret = ADOConnection::MetaTables($ttype, $showSchema);

                $this->metaTablesSQL = $save;
                return $ret;
        }

    /**
     * @param bool $auto_commit
     * @return void
     */
    function SetAutoCommit($auto_commit)
    {
        $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT, $auto_commit);
    }

        function SetTransactionMode($transaction_mode)
        {
                $this->_transmode  = $transaction_mode;
                if (empty($transaction_mode)) {
                        $this->Execute('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ');
                        return;
                }
                if (!stristr($transaction_mode, 'isolation')) {
                        $transaction_mode = 'ISOLATION LEVEL ' . $transaction_mode;
                }
                $this->Execute('SET SESSION TRANSACTION ' . $transaction_mode);
        }

        function MetaColumns($table, $normalize=true)
        {
                $this->_findschema($table, $schema);
                if ($schema) {
                        $dbName = $this->database;
                        $this->SelectDB($schema);
                }
                global $ADODB_FETCH_MODE;
                $save = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;

                if ($this->fetchMode !== false) {
                        $savem = $this->SetFetchMode(false);
                }
                $rs = $this->Execute(sprintf($this->metaColumnsSQL, $table));

                if ($schema) {
                        $this->SelectDB($dbName);
                }

                if (isset($savem)) {
                        $this->SetFetchMode($savem);
                }
                $ADODB_FETCH_MODE = $save;
                if (!is_object($rs)) {
                        $false = false;
                        return $false;
                }

                $retarr = array();
                while (!$rs->EOF){
                        $fld = new ADOFieldObject();
                        $fld->name = $rs->fields[0];
                        $type = $rs->fields[1];

                        // split type into type(length):
                        $fld->scale = null;
                        if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $query_array)) {
                                $fld->type = $query_array[1];
                                $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
                                $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
                        } elseif (preg_match('/^(.+)\((\d+)/', $type, $query_array)) {
                                $fld->type = $query_array[1];
                                $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
                        } elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $query_array)) {
                                $fld->type = $query_array[1];
                                $arr = explode(',', $query_array[2]);
                                $fld->enums = $arr;
                                $zlen = max(array_map('strlen', $arr)) - 2; // PHP >= 4.0.6
                                $fld->max_length = ($zlen > 0) ? $zlen : 1;
                        } else {
                                $fld->type = $type;
                                $fld->max_length = -1;
                        }
                        $fld->not_null = ($rs->fields[2] != 'YES');
                        $fld->primary_key = ($rs->fields[3] == 'PRI');
                        $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
                        $fld->binary = (strpos($type, 'blob') !== false);
                        $fld->unsigned = (strpos($type, 'unsigned') !== false);

                        if (!$fld->binary) {
                                $d = $rs->fields[4];
                                if ($d != '' && $d != 'NULL') {
                                        $fld->has_default = true;
                                        $fld->default_value = $d;
                                } else {
                                        $fld->has_default = false;
                                }
                        }

                        if ($save == ADODB_FETCH_NUM) {
                                $retarr[] = $fld;
                        } else {
                                $retarr[strtoupper($fld->name)] = $fld;
                        }
                        $rs->MoveNext();
                }

                $rs->Close();
                return $retarr;
        }

        // returns true or false
        function SelectDB($dbName)
        {
                $this->database = $dbName;
                $try = $this->Execute('use ' . $dbName);
                return ($try !== false);
        }

        // parameters use PostgreSQL convention, not MySQL
        function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0)
        {
                $nrows = (int) $nrows;
                $offset = (int) $offset;
                $offsetStr =($offset>=0) ? "$offset," : '';
                // jason judge, see PHPLens Issue No: 9220
                if ($nrows < 0) {
                        $nrows = '18446744073709551615';
                }

                if ($secs) {
                        $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows", $inputarr);
                } else {
                        $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows", $inputarr);
                }
                return $rs;
        }

        function SQLDate($fmt, $col=false)
        {
                if (!$col) {
                        $col = $this->sysTimeStamp;
                }
                $s = 'DATE_FORMAT(' . $col . ",'";
                $concat = false;
                $len = strlen($fmt);
                for ($i=0; $i < $len; $i++) {
                        $ch = $fmt[$i];
                        switch($ch) {

                                default:
                                        if ($ch == '\\') {
                                                $i++;
                                                $ch = substr($fmt, $i, 1);
                                        }
                                        // FALL THROUGH
                                case '-':
                                case '/':
                                        $s .= $ch;
                                        break;

                                case 'Y':
                                case 'y':
                                        $s .= '%Y';
                                        break;

                                case 'M':
                                        $s .= '%b';
                                        break;

                                case 'm':
                                        $s .= '%m';
                                        break;

                                case 'D':
                                case 'd':
                                        $s .= '%d';
                                        break;

                                case 'Q':
                                case 'q':
                                        $s .= "'),Quarter($col)";

                                        if ($len > $i+1) {
                                                $s .= ",DATE_FORMAT($col,'";
                                        } else {
                                                $s .= ",('";
                                        }
                                        $concat = true;
                                        break;

                                case 'H':
                                        $s .= '%H';
                                        break;

                                case 'h':
                                        $s .= '%I';
                                        break;

                                case 'i':
                                        $s .= '%i';
                                        break;

                                case 's':
                                        $s .= '%s';
                                        break;

                                case 'a':
                                case 'A':
                                        $s .= '%p';
                                        break;

                                case 'w':
                                        $s .= '%w';
                                        break;

                                case 'W':
                                        $s .= '%U';
                                        break;

                                case 'l':
                                        $s .= '%W';
                                        break;
                        }
                }
                $s .= "')";
                if ($concat) {
                        $s = "CONCAT($s)";
                }
                return $s;
        }

        function GenID($seqname='adodbseq',$startID=1)
        {
                $getnext = sprintf($this->_genIDSQL,$seqname);
                $holdtransOK = $this->_transOK; // save the current status
                $rs = @$this->Execute($getnext);
                if (!$rs) {
                        if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
                        $this->Execute(sprintf($this->_genSeqSQL,$seqname));
                        $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
                        if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
                        $rs = $this->Execute($getnext);
                }

                if ($rs) {
                        $this->genID = $this->_connectionID->lastInsertId($seqname);
                        $rs->Close();
                } else {
                        $this->genID = 0;
                }

                return $this->genID;
        }


        function createSequence($seqname='adodbseq',$startID=1)
        {
                if (empty($this->_genSeqSQL)) {
                        return false;
                }
                $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
                if (!$ok) {
                        return false;
                }

                return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
        }
}