⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adodb.php

📁 PhpWiki是sourceforge的一个开源项目
💻 PHP
📖 第 1 页 / 共 5 页
字号:
<?php // -*-php-*-rcs_id('$Id: ADODB.php,v 1.74 2005/02/10 19:04:22 rurban Exp $');/* Copyright 2002,2004 $ThePhpWikiProgrammingTeam This file is part of PhpWiki. PhpWiki is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PhpWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PhpWiki; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/ /** * Based on PearDB.php.  * @author: Lawrence Akka, Reini Urban * * Now (phpwiki-1.3.10) with adodb-4.22, by Reini Urban: * 1) Extended to use all available database backends, not only mysql. * 2) It uses the ultra-fast binary adodb extension if loaded. * 3) We use FETCH_NUM instead of FETCH_ASSOC (faster and more generic) * 4) To support generic iterators which return ASSOC fields, and to support queries with  *    variable columns, some trickery was needed to use recordset specific fetchMode. *    The first Execute uses the global fetchMode (ASSOC), then it's resetted back to NUM  *    and the recordset fetchmode is set to ASSOC. * 5) Transaction support, and locking as fallback. * 6) 2004-12-10 added extra page.cached_html * * phpwiki-1.3.11, by Philippe Vanhaesendonck * - pass column list to iterators so we can FETCH_NUM in all cases * * ADODB basic differences to PearDB: It pre-fetches the first row into fields,  * is dirtier in style, layout and more low-level ("worse is better"). * It has less needed basic features (modifyQuery, locks, ...), but some more  * unneeded features included: paging, monitoring and sessions, and much more drivers. * No locking (which PearDB supports in some backends), and sequences are very  * bad compared to PearDB. * Old Comments, by Lawrence Akka: * 1)  ADODB's GetRow() is slightly different from that in PEAR.  It does not  *     accept a fetchmode parameter *     That doesn't matter too much here, since we only ever use FETCHMODE_ASSOC * 2)  No need for ''s around strings in sprintf arguments - qstr puts them  *     there automatically * 3)  ADODB has a version of GetOne, but it is difficult to use it when  *     FETCH_ASSOC is in effect. *     Instead, use $rs = Execute($query); $value = $rs->fields["$colname"] * 4)  No error handling yet - could use ADOConnection->raiseErrorFn * 5)  It used to be faster then PEAR/DB at the beginning of 2002.  *     Now at August 2002 PEAR/DB with our own page cache added,  *     performance is comparable. */require_once('lib/WikiDB/backend.php');// Error handling - calls trigger_error.  NB - does not close the connection.  Does it need to?include_once('lib/WikiDB/adodb/adodb-errorhandler.inc.php');// include the main adodb filerequire_once('lib/WikiDB/adodb/adodb.inc.php');class WikiDB_backend_ADODBextends WikiDB_backend{    function WikiDB_backend_ADODB ($dbparams) {        $parsed = parseDSN($dbparams['dsn']);        $this->_dbparams = $dbparams;        $this->_parsedDSN =& $parsed;        $this->_dbh = &ADONewConnection($parsed['phptype']);        if (DEBUG & _DEBUG_SQL) {            $this->_dbh->debug = true;            $GLOBALS['ADODB_OUTP'] = '_sql_debuglog';        }        $this->_dsn = $parsed;        // persistent is defined as DSN option, or with a config value.        //   phptype://username:password@hostspec/database?persistent=false        if (!empty($parsed['persistent']) or DATABASE_PERSISTENT)            $conn = $this->_dbh->PConnect($parsed['hostspec'],$parsed['username'],                                           $parsed['password'], $parsed['database']);        else            $conn = $this->_dbh->Connect($parsed['hostspec'],$parsed['username'],                                          $parsed['password'], $parsed['database']);        // Since 1.3.10 we use the faster ADODB_FETCH_NUM,        // with some ASSOC based recordsets.        $GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_NUM;        $this->_dbh->SetFetchMode(ADODB_FETCH_NUM);        $GLOBALS['ADODB_COUNTRECS'] = false;        $prefix = isset($dbparams['prefix']) ? $dbparams['prefix'] : '';        $this->_table_names            = array('page_tbl'     => $prefix . 'page',                    'version_tbl'  => $prefix . 'version',                    'link_tbl'     => $prefix . 'link',                    'recent_tbl'   => $prefix . 'recent',                    'nonempty_tbl' => $prefix . 'nonempty');        $page_tbl = $this->_table_names['page_tbl'];        $version_tbl = $this->_table_names['version_tbl'];        $this->page_tbl_fields = "$page_tbl.id AS id, $page_tbl.pagename AS pagename, "            . "$page_tbl.hits hits";        $this->page_tbl_field_list = array('id', 'pagename', 'hits');        $this->version_tbl_fields = "$version_tbl.version AS version, "            . "$version_tbl.mtime AS mtime, "            . "$version_tbl.minor_edit AS minor_edit, $version_tbl.content AS content, "            . "$version_tbl.versiondata AS versiondata";        $this->version_tbl_field_list = array('version', 'mtime', 'minor_edit', 'content',            'versiondata');        $this->_expressions            = array('maxmajor'     => "MAX(CASE WHEN minor_edit=0 THEN version END)",                    'maxminor'     => "MAX(CASE WHEN minor_edit<>0 THEN version END)",                    'maxversion'   => "MAX(version)",                    'notempty'     => "<>''",                    'iscontent'    => "$version_tbl.content<>''");        $this->_lock_count = 0;    }    /**     * Close database connection.     */    function close () {        if (!$this->_dbh)            return;        if ($this->_lock_count) {            trigger_error("WARNING: database still locked " .                           '(lock_count = $this->_lock_count)' . "\n<br />",                          E_USER_WARNING);        }//      $this->_dbh->setErrorHandling(PEAR_ERROR_PRINT);        // prevent recursive loops.        $this->unlock(false,'force');        $this->_dbh->close();        $this->_dbh = false;    }    /*     * Fast test for wikipage.     */    function is_wiki_page($pagename) {        $dbh = &$this->_dbh;        extract($this->_table_names);        $row = $dbh->GetRow(sprintf("SELECT $page_tbl.id AS id"                                    . " FROM $nonempty_tbl, $page_tbl"                                    . " WHERE $nonempty_tbl.id=$page_tbl.id"                                    . "   AND pagename=%s",                                    $dbh->qstr($pagename)));        return $row ? $row[0] : false;    }            function get_all_pagenames() {        $dbh = &$this->_dbh;        extract($this->_table_names);        $result = $dbh->Execute("SELECT pagename"                                . " FROM $nonempty_tbl, $page_tbl"                                . " WHERE $nonempty_tbl.id=$page_tbl.id");        return $result->GetArray();    }    function numPages($filter=false, $exclude='') {        $dbh = &$this->_dbh;        extract($this->_table_names);        $result = $dbh->getRow("SELECT count(*)"                            . " FROM $nonempty_tbl, $page_tbl"                            . " WHERE $nonempty_tbl.id=$page_tbl.id");        return $result[0];    }    function increaseHitCount($pagename) {        $dbh = &$this->_dbh;        // Hits is the only thing we can update in a fast manner.        // Note that this will fail silently if the page does not        // have a record in the page table.  Since it's just the        // hit count, who cares?        $dbh->Execute(sprintf("UPDATE %s SET hits=hits+1 WHERE pagename=%s LIMIT 1",                              $this->_table_names['page_tbl'],                              $dbh->qstr($pagename)));        return;    }    /**     * Read page information from database.     */    function get_pagedata($pagename) {        $dbh = &$this->_dbh;        $row = $dbh->GetRow(sprintf("SELECT id,pagename,hits,pagedata FROM %s WHERE pagename=%s",                                    $this->_table_names['page_tbl'],                                    $dbh->qstr($pagename)));        return $row ? $this->_extract_page_data($row[3], $row[2]) : false;    }    function  _extract_page_data($data, $hits) {        if (empty($data))            return array('hits' => $hits);        else             return array_merge(array('hits' => $hits), $this->_unserialize($data));    }    function update_pagedata($pagename, $newdata) {        $dbh = &$this->_dbh;        $page_tbl = $this->_table_names['page_tbl'];        // Hits is the only thing we can update in a fast manner.        if (count($newdata) == 1 && isset($newdata['hits'])) {            // Note that this will fail silently if the page does not            // have a record in the page table.  Since it's just the            // hit count, who cares?            $dbh->Execute(sprintf("UPDATE $page_tbl SET hits=%d WHERE pagename=%s",                                  $newdata['hits'], $dbh->qstr($pagename)));            return;        }        $where = sprintf("pagename=%s", $dbh->qstr($pagename));        $dbh->BeginTrans( );        $dbh->RowLock($page_tbl,$where);                $data = $this->get_pagedata($pagename);        if (!$data) {            $data = array();            $this->_get_pageid($pagename, true); // Creates page record        }                $hits = (empty($data['hits'])) ? 0 : (int)$data['hits'];        unset($data['hits']);        foreach ($newdata as $key => $val) {            if ($key == 'hits')                $hits = (int)$val;            else if (empty($val))                unset($data[$key]);            else                $data[$key] = $val;        }        if ($dbh->Execute("UPDATE $page_tbl"                          . " SET hits=?, pagedata=?"                          . " WHERE pagename=?",                          array($hits, $this->_serialize($data),$pagename))) {            $dbh->CommitTrans( );            return true;        } else {            $dbh->RollbackTrans( );            return false;        }    }    function get_cached_html($pagename) {        $dbh = &$this->_dbh;        $page_tbl = $this->_table_names['page_tbl'];        $row = $dbh->GetRow(sprintf("SELECT cached_html FROM $page_tbl WHERE pagename=%s",                                    $dbh->qstr($pagename)));        return $row ? $row[0] : false;    }    function set_cached_html($pagename, $data) {        $dbh = &$this->_dbh;        $page_tbl = $this->_table_names['page_tbl'];        if (empty($data)) $data = '';        $rs = $dbh->Execute("UPDATE $page_tbl"                            . " SET cached_html=?"                            . " WHERE pagename=?",                            array($data, $pagename));    }    function _get_pageid($pagename, $create_if_missing = false) {        // check id_cache        global $request;        $cache =& $request->_dbi->_cache->_id_cache;        if (isset($cache[$pagename])) {            if ($cache[$pagename] or !$create_if_missing) {                return $cache[$pagename];            }        }                $dbh = &$this->_dbh;        $page_tbl = $this->_table_names['page_tbl'];        $query = sprintf("SELECT id FROM $page_tbl WHERE pagename=%s",                         $dbh->qstr($pagename));        if (! $create_if_missing ) {            $row = $dbh->GetRow($query);            return $row ? $row[0] : false;        }        $row = $dbh->GetRow($query);        if (! $row ) {            //mysql, mysqli or mysqlt            if (substr($dbh->databaseType,0,5) == 'mysql') {                // have auto-incrementing, atomic version                $rs = $dbh->Execute(sprintf("INSERT INTO $page_tbl"                                            . " (id,pagename)"                                            . " VALUES(NULL,%s)",                                            $dbh->qstr($pagename)));                $id = $dbh->_insertid();            } else {                //$id = $dbh->GenID($page_tbl . 'seq');                // Better generic version than with adodob::genID                //TODO: Does the DBM has subselects? Then we can do it with select max(id)+1                $this->lock(array('page'));                $dbh->BeginTrans( );                $dbh->CommitLock($page_tbl);                $row = $dbh->GetRow("SELECT MAX(id) FROM $page_tbl");                $id = $row[0] + 1;                $rs = $dbh->Execute(sprintf("INSERT INTO $page_tbl"                                            . " (id,pagename,hits)"                                            . " VALUES (%d,%s,0)",                                            $id, $dbh->qstr($pagename)));                if ($rs) $dbh->CommitTrans( );                else $dbh->RollbackTrans( );                $this->unlock(array('page'));            }        } else {            $id = $row[0];        }        assert($id);        return $id;    }    function get_latest_version($pagename) {        $dbh = &$this->_dbh;        extract($this->_table_names);        $row = $dbh->GetRow(sprintf("SELECT latestversion"                                    . " FROM $page_tbl, $recent_tbl"                                    . " WHERE $page_tbl.id=$recent_tbl.id"                                    . "  AND pagename=%s",                                    $dbh->qstr($pagename)));        return $row ? (int)$row[0] : false;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -