From: <var...@us...> - 2021-09-03 13:24:44
|
Revision: 10536 http://sourceforge.net/p/phpwiki/code/10536 Author: vargenau Date: 2021-09-03 13:24:39 +0000 (Fri, 03 Sep 2021) Log Message: ----------- Remove ADODB DATABASE_TYPE. Use SQL (Pear) or PDO. Modified Paths: -------------- trunk/config/config-default.ini trunk/config/config-dist.ini trunk/configurator.php trunk/doc/INSTALL.mysql trunk/doc/INSTALL.sqlite trunk/doc/README.phpwiki-auth trunk/lib/DbSession/PDO.php trunk/lib/DbSession.php trunk/lib/IniConfig.php trunk/lib/PageList.php trunk/lib/Request.php trunk/lib/WikiDB/SQL.php trunk/lib/WikiDB/backend/PDO.php trunk/lib/WikiDB/backend/file.php trunk/lib/WikiDB/backend.php trunk/lib/WikiDB.php trunk/lib/WikiGroup.php trunk/lib/WikiUser/Db.php trunk/lib/WikiUser.php trunk/lib/main.php trunk/lib/plugin/SqlResult.php trunk/lib/plugin/SystemInfo.php trunk/lib/plugin/WhoIsOnline.php trunk/lib/prepend.php trunk/lib/wikilens/RatingsDb.php trunk/locale/Makefile trunk/locale/de/LC_MESSAGES/phpwiki.mo trunk/locale/es/LC_MESSAGES/phpwiki.mo trunk/locale/fr/LC_MESSAGES/phpwiki.mo trunk/locale/it/LC_MESSAGES/phpwiki.mo trunk/locale/ja/LC_MESSAGES/phpwiki.mo trunk/locale/nl/LC_MESSAGES/phpwiki.mo trunk/locale/po/de.po trunk/locale/po/es.po trunk/locale/po/fr.po trunk/locale/po/it.po trunk/locale/po/ja.po trunk/locale/po/nl.po trunk/locale/po/phpwiki.pot trunk/locale/po/sv.po trunk/locale/po/zh.po trunk/locale/sv/LC_MESSAGES/phpwiki.mo trunk/locale/update-makefile.sh trunk/locale/zh/LC_MESSAGES/phpwiki.mo trunk/pgsrc/Help%2FPluginManagerPlugin trunk/pgsrc/ReleaseNotes trunk/tests/unit/lib/SetupWiki.php trunk/tests/unit/readme.html trunk/tests/unit/runme_all trunk/tests/unit/test.php trunk/tests/xmlrpc/xmlrpc-servers.php Removed Paths: ------------- trunk/doc/INSTALL.mssqlnative trunk/lib/DbSession/ADODB.php trunk/lib/WikiDB/ADODB.php trunk/lib/WikiDB/adodb/ trunk/lib/WikiDB/backend/ADODB.php trunk/lib/WikiDB/backend/ADODB_mssql.php trunk/lib/WikiDB/backend/ADODB_mssqlnative.php trunk/lib/WikiDB/backend/ADODB_mysql.php trunk/lib/WikiDB/backend/ADODB_oci8po.php trunk/lib/WikiDB/backend/ADODB_postgres7.php trunk/lib/WikiDB/backend/ADODB_sqlite.php trunk/lib/WikiUser/AdoDb.php trunk/locale/.exclude Modified: trunk/config/config-default.ini =================================================================== --- trunk/config/config-default.ini 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/config/config-default.ini 2021-09-03 13:24:39 UTC (rev 10536) @@ -51,7 +51,7 @@ INSECURE_ACTIONS_LOCALHOST_ONLY = true ENABLE_MODERATEDPAGE_ALL = false ACCESS_LOG = "" -; ACCESS_LOG_SQL: on SQL or ADODB 2, else 0 +; ACCESS_LOG_SQL: on SQL 2, else 0 ; ACCESS_LOG_SQL = 0 ; COMPRESS_OUTPUT = true CACHE_CONTROL = LOOSE Modified: trunk/config/config-dist.ini =================================================================== --- trunk/config/config-dist.ini 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/config/config-dist.ini 2021-09-03 13:24:39 UTC (rev 10536) @@ -284,7 +284,7 @@ ; ; If defined (e.g. 1) read-access is done via SQL. ; If flag 2 is set, phpwiki also writes. Default on SQL database. -; This must use DATABASE_TYPE = SQL or ADODB or PDO. +; This must use DATABASE_TYPE = SQL or PDO. ; ACCESS_LOG_SQL = 0 ; disable SQL access logging ; ACCESS_LOG_SQL = 1 ; phpwiki reads, apache mod_log_sql writes ;ACCESS_LOG_SQL = 2 ; read + write @@ -392,8 +392,7 @@ ; Select the database backend type: ; ; SQL: access one of several SQL databases using the PEAR DB library. -; ADODB: uses the ADODB library for data access. (most general) -; PDO: The new PHP5 dataobkject library. (experimental, no paging yet) +; PDO: The new PHP5 library. ; dba: use one of the standard UNIX dbm libraries. Use BerkeleyDB (db3,4) (fastest) ; file: use a serialized file database. (easiest) ; flatfile: use a flat file database. (experimental, readable, slow) @@ -519,8 +518,7 @@ ; BogoLogin: WikiWord username, with no *actual* password checking, ; although the user will still have to enter one. ; PersonalPage: Store passwords in the users homepage metadata (simple) -; Db: Use DBAUTH_AUTH_* (see below) with PearDB or -; ADODB only. +; Db: Use DBAUTH_AUTH_* (see below) with PearDB ; LDAP: Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN ; IMAP: Authenticate against IMAP_AUTH_HOST (email account) ; POP3: Authenticate against POP3_AUTH_HOST (email account) Modified: trunk/configurator.php =================================================================== --- trunk/configurator.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/configurator.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -674,15 +674,14 @@ new _define_selection("DATABASE_TYPE", array('dba' => "dba", 'SQL' => "SQL PEAR", - 'ADODB' => "SQL ADODB", 'PDO' => "PDO", 'file' => "flatfile")/*, " Select the database backend type: Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest. -Choose ADODB or SQL to use an SQL database with ADODB or PEAR. -Choose PDO to use an SQL database. (experimental, no paging yet) +Choose SQL to use an SQL database with PEAR. +Choose PDO to use an SQL database. flatfile is simple and slow. -Recommended is dba or SQL: PEAR or ADODB."*/); +Recommended is dba or SQL: PEAR."*/); $properties["SQL DSN Setup"] = new unchangeable_variable('_sqldsnstuff', "", " @@ -705,7 +704,7 @@ DATABASE_DSN = pgsql://localhost/user_phpwiki </pre>"); -// Choose ADODB or SQL to use an SQL database with ADODB or PEAR. +// Choose SQL to use an SQL database with PEAR. // Choose dba to use one of the standard UNIX dbm libraries. $properties["SQL Type"] = @@ -715,9 +714,9 @@ 'mssql' => "Microsoft SQL Server", 'mssqlnative' => "Microsoft SQL Server (native)", 'oci8' => "Oracle 8", - 'mysqli' => "mysqli (only ADODB)", - 'mysqlt' => "mysqlt (only ADODB)", - 'ODBC' => "ODBC (only ADODB or PDO)", + 'mysqli' => "mysqli", + 'mysqlt' => "mysqlt)", + 'ODBC' => "ODBC (only PDO)", 'firebird' => "Firebird (only PDO)", 'oracle' => "Oracle (only PDO)", ), " @@ -858,7 +857,7 @@ <dt>PersonalPage</dt> <dd>Store passwords in the users homepage metadata (simple)</dd> <dt>Db</dt> - <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd> + <dd>Use DBAUTH_AUTH_* (see below) with PearDB only.</dd> <dt>LDAP</dt> <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN.</dd> <dt>IMAP</dt> Deleted: trunk/doc/INSTALL.mssqlnative =================================================================== --- trunk/doc/INSTALL.mssqlnative 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/doc/INSTALL.mssqlnative 2021-09-03 13:24:39 UTC (rev 10536) @@ -1,49 +0,0 @@ -Installing phpwiki with MS SQL Server Native Driver for ADOdb ------------------------------------------------------------ - -Microsoft has been working hard to get support for their products -into Open Source projects. The MS SQL Server 2005 Driver for ADOdb -is one step in that direction. The following is instructions on how -to get and install the new mssql php driver for ADOdb as well as -how to get the new driver to work with phpWiki. - -As of the writing of this walkthrough, the latest version of the PHP -driver for SQL Server 2005 is the May 2008 Community Technical Preview. -If you don't already have a copy of the SQL Server 2005 for PHP -driver installed on your server, you can get a copy at: -http://www.microsoft.com/sql/technologies/php/default.mspx - -This assumes that you have PHP 5 installed as well as a working copy of -any edition of SQL Server 2005 or SQL Server 2000 (including Express -Edition). If you do not have a copy of the free SQL Server 2005 Express -Edition you can download it from: -http://go.microsoft.com/fwlink/?LinkId=64064 - -1. If you do not have a database created already, create one using - the SQL Server Management tool. You can get the free Express version at: - http://www.microsoft.com/downloads/details.aspx?FamilyId=C243A5AE-4BD1- - 4E3D-94B8-5A0F62BF7796&displaylang=en - -2. If necessary create a user for that database which has the rights - to select, insert, update, delete. For more information on how to use - SQL Server 2005 you can download SQL Server 2005 Books Online at: - http://www.microsoft.com/downloads/details.aspx?FamilyId=BE6A2C5D-00DF- - 4220-B133-29C1E0B6585F&displaylang=en - -3. Create the tables and functions inside your database by running the SQL - file included with the phpWiki project located at: - schemas/sqlsrv-initialize.sql - -4. Edit the DATABASE settings in config/config.ini to reflect your settings. - - a) DATABASE_TYPE should be set to 'ADODB' (case sensitive) - b) DATABASE_DSN should be set to something like: - 'mssqlnative://username:password@pathtosqlserver/databasename' - c) Note that if you set DATABASE_PREFIX to a non-empty string, you will - have to edit schemas/sqlsrv-initialize.sql before you perform step - three (above). You might also edit schemas/sqlsrv-destroy.sql at the - same time, so you don't forget. - - Note: DATABASE_DIRECTORY and DATABASE_DBA_HANDLER are ignored for mssql. - -That's it. phpWiki should work now. Modified: trunk/doc/INSTALL.mysql =================================================================== --- trunk/doc/INSTALL.mysql 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/doc/INSTALL.mysql 2021-09-03 13:24:39 UTC (rev 10536) @@ -40,7 +40,7 @@ 4. Edit the DATABASE settings in config/config.ini to reflect your settings. - a) DATABASE_TYPE should be set to 'SQL' or 'ADODB'. + a) DATABASE_TYPE should be set to 'SQL'. b) DATABASE_DSN should be set to something like 'mysql://guest@unix(/var/lib/mysql/mysql.sock)/phpwiki". (where 'phpwiki' is the mysql database name.) Modified: trunk/doc/INSTALL.sqlite =================================================================== --- trunk/doc/INSTALL.sqlite 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/doc/INSTALL.sqlite 2021-09-03 13:24:39 UTC (rev 10536) @@ -20,7 +20,6 @@ Edit the DATABASE settings in config/config.ini to reflect your settings. a) DATABASE_TYPE must be set to 'SQL'. - ADODB not yet. This is planned for the 1.4.0 release. b) DATABASE_DSN should be set to something like DATABASE_DSN = "sqlite:////tmp/phpwiki-sqlite.db?mode=0664&persistent=1" Modified: trunk/doc/README.phpwiki-auth =================================================================== --- trunk/doc/README.phpwiki-auth 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/doc/README.phpwiki-auth 2021-09-03 13:24:39 UTC (rev 10536) @@ -126,8 +126,8 @@ * __~BogoLogin__: This will eventually replace the old ALLOW_BOGO_LOGIN constant, but it will require PASSWORD_LENGTH_MINIMUM. So non-empty passwords can be disabled. * __~PersonalPage__: Store passwords in the users homepage metadata (simple) -* __Db__: Use $DBAuthParams~[~] (see below) with PearDB or ADODB only. - If 'auth_dsn' is undefined, and wiki pages are stored via SQL or ADODB, +* __Db__: Use $DBAuthParams~[~] (see below) with PearDB only. + If 'auth_dsn' is undefined, and wiki pages are stored via SQL, it uses the same database. (fastest) * __LDAP__: Authenticate against LDAP_AUTH_HOST with the LDAP_AUTH_SEARCH settings * __IMAP__: Authenticate against IMAP_AUTH_HOST (e.g. an existing email account) @@ -170,9 +170,7 @@ The database can be external like radius, phpnuke, courier authmysql, apache auth_mysql or just a simple user table within phpwiki. The most likely auth_dsn option is the same dsn as the wikipages, in -fact if it's empty $DBParams~['dsn'~] is used. If -$DBParams~['db_type'~] is not ADODB, the Pear DB library is used -(db_type = SQL). +fact if it's empty $DBParams~['dsn'~] is used. This is the list of the available options and some examples. For the statements we use the following symbolic variables: $user_id : loginname @@ -181,9 +179,6 @@ $groupname : groupname Note: The symbolic variables (like "$password", ...) must be enclosed in double quotes! -ADODB Warning: With ADODB we must currently define the correct alias names: SELECT db_column as name -This requirement will go away when we switch to FETCH_ROW instead of the slower FETCH_ASSOC -(scheduled for 1.4.0) ;auth_dsn: 'mysql://user@password:localhost/phpwiki' Deleted: trunk/lib/DbSession/ADODB.php =================================================================== --- trunk/lib/DbSession/ADODB.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/DbSession/ADODB.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -1,256 +0,0 @@ -<?php -/** - * Copyright © 2005 $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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * SPDX-License-Identifier: GPL-2.0-or-later - * - */ - -/** - * ADODB db sessions, based on pear DB Sessions. - * - * @author: Reini Urban - */ - -class DbSession_ADODB - extends DbSession -{ - public $_backend_type = "ADODB"; - - function __construct($dbh, $table) - { - $this->_dbh = $dbh; - $this->_table = $table; - - session_set_save_handler(array(&$this, 'open'), - array(&$this, 'close'), - array(&$this, 'read'), - array(&$this, 'write'), - array(&$this, 'destroy'), - array(&$this, 'gc')); - } - - function & _connect() - { - global $request; - static $parsed = false; - $dbh = &$this->_dbh; - if (!$dbh or !is_resource($dbh->_connectionID)) { - if (!$parsed) $parsed = parseDSN($request->_dbi->getParam('dsn')); - $this->_dbh = ADONewConnection($parsed['phptype']); // Probably only MySql works just now - $this->_dbh->Connect($parsed['hostspec'], $parsed['username'], - $parsed['password'], $parsed['database']); - $dbh = &$this->_dbh; - } - return $dbh; - } - - function query($sql) - { - return $this->_dbh->Execute($sql); - } - - // adds surrounding quotes - function quote($string) - { - return $this->_dbh->qstr($string); - } - - function _disconnect() - { - if (0 and $this->_dbh) - $this->_dbh->close(); - } - - /** - * Opens a session. - * - * Actually this function is a fake for session_set_save_handle. - * @param string $save_path a path to stored files - * @param string $session_name a name of the concrete file - * @return boolean true just a variable to notify PHP that everything - * is good. - */ - public function open($save_path, $session_name) - { - //$this->log("_open($save_path, $session_name)"); - return true; - } - - /** - * Closes a session. - * - * This function is called just after <i>write</i> call. - * - * @return boolean true just a variable to notify PHP that everything - * is good. - */ - public function close() - { - //$this->log("_close()"); - return true; - } - - /** - * Reads the session data from DB. - * - * @param string $id an id of current session - * @return string - */ - public function read($id) - { - //$this->log("_read($id)"); - $dbh = $this->_connect(); - $table = $this->_table; - $qid = $dbh->qstr($id); - $res = ''; - $row = $dbh->GetRow("SELECT sess_data FROM $table WHERE sess_id=$qid"); - if ($row) - $res = $row[0]; - $this->_disconnect(); - if (!empty($res) and preg_match('|^[a-zA-Z0-9/+=]+$|', $res)) - $res = base64_decode($res); - if (strlen($res) > 4000) { - // trigger_error("Overlarge session data! ".strlen($res). " gt. 4000", E_USER_WARNING); - $res = preg_replace('/s:6:"_cache";O:12:"WikiDB_cache".+}$/', "", $res); - $res = preg_replace('/s:12:"_cached_html";s:.+",s:4:"hits"/', 's:4:"hits"', $res); - if (strlen($res) > 4000) { - $res = ''; - } - } - return $res; - } - - /** - * Saves the session data into DB. - * - * Just a comment: The "write" handler is not - * executed until after the output stream is closed. Thus, - * output from debugging statements in the "write" handler - * will never be seen in the browser. If debugging output - * is necessary, it is suggested that the debug output be - * written to a file instead. - * - * @param string $id - * @param string $sess_data - * @return boolean true if data saved successfully and false - * otherwise. - */ - public function write($id, $sess_data) - { - /** - * @var WikiRequest $request - */ - global $request; - - if (defined("WIKI_XMLRPC") or defined("WIKI_SOAP")) return false; - - $dbh = $this->_connect(); - $table = $this->_table; - $qid = $dbh->qstr($id); - $qip = $dbh->qstr($request->get('REMOTE_ADDR')); - $time = $dbh->qstr(time()); - - // postgres can't handle binary data in a TEXT field. - if (is_a($dbh, 'ADODB_postgres64')) - $sess_data = base64_encode($sess_data); - $qdata = $dbh->qstr($sess_data); - - $dbh->execute("DELETE FROM $table WHERE sess_id=$qid"); - $rs = $dbh->execute("INSERT INTO $table" - . " (sess_id, sess_data, sess_date, sess_ip)" - . " VALUES ($qid, $qdata, $time, $qip)"); - $result = !$rs->EOF; - if ($result) $rs->free(); - $this->_disconnect(); - return $result; - } - - /** - * Destroys a session. - * - * Removes a session from the table. - * - * @param string $id - * @return boolean true - */ - public function destroy($id) - { - $dbh = $this->_connect(); - $table = $this->_table; - $qid = $dbh->qstr($id); - - $dbh->Execute("DELETE FROM $table WHERE sess_id=$qid"); - - $this->_disconnect(); - return true; - } - - /** - * Cleans out all expired sessions. - * - * @param int $maxlifetime session's time to live. - * @return boolean true - */ - public function gc($maxlifetime) - { - $dbh = $this->_connect(); - $table = $this->_table; - $threshold = time() - $maxlifetime; - - $dbh->Execute("DELETE FROM $table WHERE sess_date < $threshold"); - - $this->_disconnect(); - return true; - } - - // WhoIsOnline support - // TODO: ip-accesstime dynamic blocking API - function currentSessions() - { - $sessions = array(); - $dbh = $this->_connect(); - $table = $this->_table; - $rs = $dbh->Execute("SELECT sess_data,sess_date,sess_ip FROM $table ORDER BY sess_date DESC"); - if ($rs->EOF) { - $rs->free(); - return $sessions; - } - while (!$rs->EOF) { - $row = $rs->fetchRow(); - $data = $row[0]; - $date = $row[1]; - $ip = $row[2]; - if (preg_match('|^[a-zA-Z0-9/+=]+$|', $data)) - $data = base64_decode($data); - if ($date < 908437560 or $date > 1588437560) - $date = 0; - // session_data contains the <variable name> + "|" + <packed string> - // we need just the wiki_user object (might be array as well) - $user = strstr($data, "wiki_user|"); - $sessions[] = array('wiki_user' => substr($user, 10), // from "O:" onwards - 'date' => $date, - 'ip' => $ip); - $rs->MoveNext(); - } - $rs->free(); - $this->_disconnect(); - return $sessions; - } -} Modified: trunk/lib/DbSession/PDO.php =================================================================== --- trunk/lib/DbSession/PDO.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/DbSession/PDO.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -120,9 +120,6 @@ $res = ''; } $this->_disconnect(); - if (!empty($res) and is_a($dbh, 'ADODB_postgres64')) { - $res = base64_decode($res); - } if (strlen($res) > 4000) { // trigger_error("Overlarge session data! ".strlen($res). " gt. 4000", E_USER_WARNING); $res = preg_replace('/s:6:"_cache";O:12:"WikiDB_cache".+}$/', "", $res); @@ -163,10 +160,6 @@ $time = time(); $remote_addr = $request->get('REMOTE_ADDR'); - // postgres can't handle binary data in a TEXT field. - if (is_a($dbh, 'ADODB_postgres64')) - $sess_data = base64_encode($sess_data); - $this->_backend->beginTransaction(); $delete = $dbh->prepare("DELETE FROM $table WHERE sess_id=?"); $delete->bindParam(1, $id, PDO::PARAM_STR, 32); Modified: trunk/lib/DbSession.php =================================================================== --- trunk/lib/DbSession.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/DbSession.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -24,7 +24,7 @@ */ /** - * Store sessions data in Pear DB / ADODB / dba / PDO, .... + * Store sessions data in Pear DB / dba / PDO, .... * * History * @@ -31,7 +31,7 @@ * Originally by Stanislav Shramko <st...@mo...> * Minor rewrite by Reini Urban <ru...@x-...> for Phpwiki. * Quasi-major rewrite/decruft/fix by Jeff Dairiki <da...@da...>. - * ADODB, dba and PDO classes by Reini Urban. + * dba and PDO classes by Reini Urban. * */ class DbSession Modified: trunk/lib/IniConfig.php =================================================================== --- trunk/lib/IniConfig.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/IniConfig.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -320,7 +320,7 @@ unset($rsdef[$item]); } } - $valid_database_types = array('SQL', 'ADODB', 'PDO', 'dba', 'file', 'flatfile'); + $valid_database_types = array('SQL', 'PDO', 'dba', 'file', 'flatfile'); if (!in_array(DATABASE_TYPE, $valid_database_types)) trigger_error(sprintf("Invalid DATABASE_TYPE=%s. Choose one of %s", DATABASE_TYPE, join(",", $valid_database_types)), @@ -333,7 +333,7 @@ // USE_DB_SESSION default logic: if (!defined('USE_DB_SESSION')) { if ($DBParams['db_session_table'] - and in_array($DBParams['dbtype'], array('SQL', 'ADODB', 'PDO', 'dba')) + and in_array($DBParams['dbtype'], array('SQL', 'PDO', 'dba')) ) { define('USE_DB_SESSION', true); } else { @@ -391,7 +391,7 @@ if (!defined('ACCESS_LOG_SQL')) { if (array_key_exists('ACCESS_LOG_SQL', $rs)) { // WikiDB_backend::isSql() not yet loaded - if (!in_array(DATABASE_TYPE, array('SQL', 'ADODB', 'PDO'))) { + if (!in_array(DATABASE_TYPE, array('SQL', 'PDO'))) { // override false config setting on no SQL WikiDB database. define('ACCESS_LOG_SQL', 0); } @@ -398,7 +398,7 @@ // SQL defaults to ACCESS_LOG_SQL = 2 } else { define('ACCESS_LOG_SQL', - in_array(DATABASE_TYPE, array('SQL', 'ADODB', 'PDO')) ? 2 : 0); + in_array(DATABASE_TYPE, array('SQL', 'PDO')) ? 2 : 0); } } Modified: trunk/lib/PageList.php =================================================================== --- trunk/lib/PageList.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/PageList.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -985,10 +985,6 @@ $res = $dbi->_backend->_dbh->getOne("SELECT max(length(pagename)) FROM $page_tbl"); if (DB::isError($res) || empty($res)) return false; else return $res; - } elseif (is_a($dbi, 'WikiDB_ADODB')) { - extract($dbi->_backend->_table_names); - $row = $dbi->_backend->_dbh->getRow("SELECT max(length(pagename)) FROM $page_tbl"); - return $row ? $row[0] : false; } else return false; } Modified: trunk/lib/Request.php =================================================================== --- trunk/lib/Request.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/Request.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -821,8 +821,8 @@ if ($do_sql) { global $DBParams; - if (!in_array($DBParams['dbtype'], array('SQL', 'ADODB', 'PDO'))) { - trigger_error(_("Unsupported database backend for ACCESS_LOG_SQL. Need DATABASE_TYPE=SQL or ADODB or PDO.")); + if (!in_array($DBParams['dbtype'], array('SQL', 'PDO'))) { + trigger_error(_("Unsupported database backend for ACCESS_LOG_SQL. Need DATABASE_TYPE=SQL or PDO.")); } else { $this->logtable = (!empty($DBParams['prefix']) ? $DBParams['prefix'] : '') . "accesslog"; } Deleted: trunk/lib/WikiDB/ADODB.php =================================================================== --- trunk/lib/WikiDB/ADODB.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/WikiDB/ADODB.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -1,140 +0,0 @@ -<?php -/** - * Copyright © 2001,2003 Jeff Dairiki - * Copyright © 2001-2002 Carsten Klapp - * Copyright © 2004-2010 Reini Urban - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * SPDX-License-Identifier: GPL-2.0-or-later - * - */ - -require_once 'lib/WikiDB.php'; - -/** - * WikiDB layer for ADODB, which does nothing more than calling the - * mysql-specific ADODB backend. - * Support for a newer adodb library, the adodb extension library - * and more databases will come with PhpWiki v1.3.10 - * - * @author: Lawrence Akka, Reini Urban - */ - -class WikiDB_ADODB extends WikiDB -{ - function __construct($dbparams) - { - $backend = 'ADODB'; - if (is_array($dbparams['dsn'])) - $backend = $dbparams['dsn']['phptype']; - elseif (preg_match('/^(\w+):/', $dbparams['dsn'], $m)) - $backend = $m[1]; - // Do we have a override? (currently: mysql, sqlite, oracle, mssql, oci8po, postgres7) - // TODO: mysqlt (innodb or bdb) - if ($backend == 'pgsql') { // PearDB DSN cross-compatibility hack (for unit testing) - $backend = 'postgres7'; - if (is_string($dbparams['dsn'])) - $dbparams['dsn'] = $backend . ':' . substr($dbparams['dsn'], 6); - } - if (findFile("lib/WikiDB/backend/ADODB_" . $backend . ".php", true)) { - $backend = 'ADODB_' . $backend; - } else { - $backend = 'ADODB'; - } - include_once 'lib/WikiDB/backend/' . $backend . '.php'; - $backend_class = "WikiDB_backend_" . $backend; - $backend = new $backend_class($dbparams); - if (!$backend->_dbh->_connectionID) return; - parent::__construct($backend, $dbparams); - } - - /* - * Determine whether page exists (in non-default form). - * @see WikiDB::isWikiPage for the slow generic version - */ - public function isWikiPage($pagename) - { - $pagename = (string)$pagename; - if ($pagename === '') { - return false; - } - if (!array_key_exists($pagename, $this->_cache->_id_cache)) { - $this->_cache->_id_cache[$pagename] = $this->_backend->is_wiki_page($pagename); - } - return $this->_cache->_id_cache[$pagename]; - } - - // add surrounding quotes '' if string - public function quote($s) - { - if (is_int($s) || is_double($s)) { - return $s; - } elseif (is_bool($s)) { - return $s ? 1 : 0; - } elseif (is_null($s)) { - return 'NULL'; - } else { - return $this->_backend->_dbh->qstr($s); - } - } - - // ADODB handles everything as string - // Don't add surrounding quotes '', same as in PearDB - public function qstr($in) - { - return $this->_backend->_dbh->addq($in); - } - - public function isOpen() - { - /** - * @var WikiRequest $request - */ - global $request; - - if (!$request->_dbi) { - return false; - } - return is_resource($this->_backend->connection()); - } - - // SQL result: for simple select or create/update queries - // returns the database specific resource type - public function genericSqlQuery($sql, $args = array()) - { - if ($args) - $result = $this->_backend->_dbh->Execute($sql, $args); - else - $result = $this->_backend->_dbh->Execute($sql); - if (!$result) { - trigger_error("SQL Error: " . $this->_backend->_dbh->ErrorMsg(), E_USER_WARNING); - return false; - } else { - return $result; - } - } - - // SQL iter: for simple select or create/update queries - // returns the generic iterator object (count, next) - public function genericSqlIter($sql, $field_list = NULL) - { - $result = $this->genericSqlQuery($sql); - return new WikiDB_backend_ADODB_generic_iter($this->_backend, $result, $field_list); - } - -} Modified: trunk/lib/WikiDB/SQL.php =================================================================== --- trunk/lib/WikiDB/SQL.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/WikiDB/SQL.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -34,7 +34,7 @@ $backend = $dbparams['dsn']['phptype']; elseif (preg_match('/^(\w+):/', $dbparams['dsn'], $m)) $backend = $m[1]; - if ($backend == 'postgres7') { // ADODB cross-compatibility hack (for unit testing) + if ($backend == 'postgres7') { $backend = 'pgsql'; if (is_string($dbparams['dsn'])) $dbparams['dsn'] = $backend . ':' . substr($dbparams['dsn'], 10); Deleted: trunk/lib/WikiDB/backend/ADODB.php =================================================================== --- trunk/lib/WikiDB/backend/ADODB.php 2021-09-03 11:30:25 UTC (rev 10535) +++ trunk/lib/WikiDB/backend/ADODB.php 2021-09-03 13:24:39 UTC (rev 10536) @@ -1,1492 +0,0 @@ -<?php -/** - * Copyright © 2002,2004,2005,2006 $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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * SPDX-License-Identifier: GPL-2.0-or-later - * - */ - -/** - * Based on PearDB.php. - * @author: Lawrence Akka, Reini Urban - * - * Now (since 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 - * phpwiki-1.3.12: get rid of ISNULL - * phpwiki-1.3.13: tsearch2 and stored procedures - * - * 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 file -require_once 'lib/WikiDB/adodb/adodb.inc.php'; - -class WikiDB_backend_ADODB - extends WikiDB_backend -{ - - function __construct($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 - - //FIXME: how to catch connection errors for dbamin_user? - 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']); - if (!$conn) return; - - // 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 AS hits"; - $this->links_field_list = array('id', 'pagename'); - $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->unlock(array(), '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(); - } - - /* - * filter (nonempty pages) currently ignored - */ - 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", - $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; - } - - public 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 true; - } - $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 = ''; - $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]; - } - } - - // attributes play this game. - if ($pagename === '') return 0; - - $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) { - //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); - if (0 and $dbh->hasGenID) { - // requires create permissions - $id = $dbh->GenID($page_tbl . "_id"); - } else { - // Better generic version than with adodb::genID - $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; - } - - function get_previous_version($pagename, $version) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - // Use SELECTLIMIT for maximum portability - $rs = $dbh->SelectLimit(sprintf("SELECT version" - . " FROM $version_tbl, $page_tbl" - . " WHERE $version_tbl.id=$page_tbl.id" - . " AND pagename=%s" - . " AND version < %d" - . " ORDER BY version DESC", - $dbh->qstr($pagename), - $version), - 1); - return $rs->fields ? (int)$rs->fields[0] : false; - } - - /** - * Get version data. - * - * @param string $pagename Name of the page - * @param int $version Which version to get - * @param bool $want_content Do we need content? - * - * @return array|false The version data, or false if specified version does not exist. - */ - function get_versiondata($pagename, $version, $want_content = false) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - extract($this->_expressions); - - assert(is_string($pagename) and $pagename != ''); - assert($version > 0); - - // FIXME: optimization: sometimes don't get page data? - if ($want_content) { - $fields = $this->page_tbl_fields - . ",$page_tbl.pagedata AS pagedata," - . $this->version_tbl_fields; - } else { - $fields = $this->page_tbl_fields . ", '' AS pagedata" - . ", $version_tbl.version AS version, $version_tbl.mtime AS mtime, " - . "$version_tbl.minor_edit AS minor_edit, $iscontent AS have_content, " - . "$version_tbl.versiondata as versiondata"; - } - $row = $dbh->GetRow(sprintf("SELECT $fields" - . " FROM $page_tbl, $version_tbl" - . " WHERE $page_tbl.id=$version_tbl.id" - . " AND pagename=%s" - . " AND version=%d", - $dbh->qstr($pagename), $version)); - return $row ? $this->_extract_version_data_num($row, $want_content) : false; - } - - private function _extract_version_data_num($row, $want_content) - { - if (!$row) - return false; - - //$id &= $row[0]; - //$pagename &= $row[1]; - $data = empty($row[8]) ? array() : $this->_unserialize($row[8]); - $data['mtime'] = $row[5]; - $data['is_minor_edit'] = !empty($row[6]); - if ($want_content) { - $data['%content'] = $row[7]; - } else { - $data['%content'] = !empty($row[7]); - } - if (!empty($row[3])) { - $data['%pagedata'] = $this->_extract_page_data($row[3], $row[2]); - } - return $data; - } - - function _extract_version_data_assoc($row) - { - if (!$row) - return false; - - extract($row); - $data = empty($versiondata) ? array() : $this->_unserialize($versiondata); - $data['mtime'] = $mtime; - $data['is_minor_edit'] = !empty($minor_edit); - if (isset($content)) - $data['%content'] = $content; - elseif ($have_content) - $data['%content'] = true; else - $data['%content'] = ''; - if (!empty($pagedata)) { - // hmm, $pagedata = is already extracted by WikiDB_backend_ADODB_iter - //$data['%pagedata'] = $this->_extract_page_data($pagedata, $hits); - $data['%pagedata'] = $pagedata; - } - return $data; - } - - /* - * Create a new revision of a page. - */ - function set_versiondata($pagename, $version, $data) - { - $dbh = &$this->_dbh; - $version_tbl = $this->_table_names['version_tbl']; - - $minor_edit = (int)!empty($data['is_minor_edit']); - unset($data['is_minor_edit']); - - $mtime = (int)$data['mtime']; - unset($data['mtime']); - assert(!empty($mtime)); - - $content = isset($data['%content']) ? (string)$data['%content'] : ''; - unset($data['%content']); - unset($data['%pagedata']); - - $this->lock(array('page', 'recent', 'version', 'nonempty')); - $dbh->BeginTrans(); - $dbh->CommitLock($version_tbl); - $id = $this->_get_pageid($pagename, true); - $dbh->Execute(sprintf("DELETE FROM $version_tbl" - . " WHERE id=%d AND version=%d", - $id, $version)); - $rs = $dbh->Execute("INSERT INTO $version_tbl" - . " (id,version,mtime,minor_edit,content,versiondata)" - . " VALUES(?,?,?,?,?,?)", - array($id, $version, $mtime, $minor_edit, - $content, $this->_serialize($data))); - $this->_update_recent_table($id); - $this->_update_nonempty_table($id); - if ($rs) { - $dbh->CommitTrans(); - } else { - $dbh->RollbackTrans(); - } - $this->unlock(array('page', 'recent', 'version', 'nonempty')); - } - - /* - * Delete an old revision of a page. - */ - function delete_versiondata($pagename, $version) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - - $this->lock(array('version')); - if (($id = $this->_get_pageid($pagename))) { - $dbh->Execute("DELETE FROM $version_tbl" - . " WHERE id=$id AND version=$version"); - $this->_update_recent_table($id); - // This shouldn't be needed (as long as the latestversion - // never gets deleted.) But, let's be safe. - $this->_update_nonempty_table($id); - } - $this->unlock(array('version')); - } - - /* - * Delete page from the database with backup possibility. - * i.e save_page('') and DELETE nonempty id - * - * deletePage increments latestversion in recent to a non-existent version, - * and removes the nonempty row, - * so that get_latest_version returns id+1 and get_previous_version returns prev id - * and page->exists returns false. - */ - function delete_page($pagename) - { - /** - * @var WikiRequest $request - */ - global $request; - - $dbh = &$this->_dbh; - extract($this->_table_names); - - $dbh->BeginTrans(); - $dbh->CommitLock($recent_tbl); - if (($id = $this->_get_pageid($pagename)) === false) { - $dbh->RollbackTrans(); - return false; - } - $mtime = time(); - $user =& $request->_user; - $meta = array('author' => $user->getId(), - 'author_id' => $user->getAuthenticatedId(), - 'mtime' => $mtime); - $this->lock(array('version', 'recent', 'nonempty', 'page', 'link')); - $version = $this->get_latest_version($pagename); - if ($dbh->Execute("UPDATE $recent_tbl SET latestversion=latestversion+1," - . "latestmajor=latestversion+1,latestminor=NULL WHERE id=$id") - and $dbh->Execute("INSERT INTO $version_tbl" - . " (id,version,mtime,minor_edit,content,versiondata)" - . " VALUES(?,?,?,?,?,?)", - array($id, $version + 1, $mtime, 0, - '', $this->_serialize($meta))) - and $dbh->Execute("DELETE FROM $nonempty_tbl WHERE id=$id") - // need to keep perms and LOCKED, otherwise you can reset the perm - // by action=remove and re-create it with default perms - // keep hits but delete meta-data - //and $dbh->Execute("UPDATE $page_tbl SET pagedata='' WHERE id=$id") - ) { - $this->set_links($pagename, array()); - $this->unlock(array('version', 'recent', 'nonempty', 'page', 'link')); - $dbh->CommitTrans(); - return true; - } else { - $this->unlock(array('version', 'recent', 'nonempty', 'page', 'link')); - $dbh->RollbackTrans(); - return false; - } - } - - /* - * Delete page completely from the database. - */ - function purge_page($pagename) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - - $this->lock(array('version', 'recent', 'nonempty', 'page', 'link')); - if (($id = $this->_get_pageid($pagename))) { - $dbh->Execute("DELETE FROM $nonempty_tbl WHERE id=$id"); - $dbh->Execute("DELETE FROM $recent_tbl WHERE id=$id"); - $dbh->Execute("DELETE FROM $version_tbl WHERE id=$id"); - $this->set_links($pagename, array()); - $row = $dbh->GetRow("SELECT COUNT(*) FROM $link_tbl WHERE linkto=$id"); - if ($row and $row[0]) { - // We're still in the link table (dangling link) so we can't delete this - // altogether. - $dbh->Execute("UPDATE $page_tbl SET hits=0, pagedata='' WHERE id=$id"); - $result = 0; - } else { - $dbh->Execute("DELETE FROM $page_tbl WHERE id=$id"); - $result = 1; - } - } else { - $result = -1; // already purged or not existing - } - $this->unlock(array('version', 'recent', 'nonempty', 'page', 'link')); - return $result; - } - - /** - * Set links for page. - * - * @param string $pagename Page name - * @param array $links List of page(names) which page links to. - */ - function set_links($pagename, $links) - { - // Update link table. - // FIXME: optimize: mysql can do this all in one big INSERT/REPLACE. - - $dbh = &$this->_dbh; - extract($this->_table_names); - - $this->lock(array('link')); - $pageid = $this->_get_pageid($pagename, true); - - $oldlinks = $dbh->getAssoc("SELECT $link_tbl.linkto as id, page.pagename FROM $link_tbl" - . " JOIN page ON ($link_tbl.linkto = page.id)" - . " WHERE linkfrom=$pageid"); - // Delete current links, - $dbh->Execute("DELETE FROM $link_tbl WHERE linkfrom=$pageid"); - // and insert new links. Faster than checking for all single links - if ($links) { - foreach ($links as $link) { - $linkto = $link['linkto']; - if ($linkto === "") { // ignore attributes - continue; - } - if (isset($link['relation'])) - $relation = $this->_get_pageid($link['relation'], true); - else - $relation = 0; - // avoid duplicates - if (isset($linkseen[$linkto]) and !$relation) { - continue; - } - if (!$relation) { - $linkseen[$linkto] = true; - } - $linkid = $this->_get_pageid($linkto, true); - assert($linkid); - if ($relation) { - $dbh->Execute("INSERT INTO $link_tbl (linkfrom, linkto, relation)" - . " VALUES ($pageid, $linkid, $relation)"); - } else { - $dbh->Execute("INSERT INTO $link_tbl (linkfrom, linkto)" - . " VALUES ($pageid, $linkid)"); - } - if ($oldlinks and array_key_exists($linkid, $oldlinks)) { - // This was also in the previous page - unset($oldlinks[$linkid]); - } - } - } - $this->unlock(array('link')); - } - - /** - * Find pages which link to or are linked from a page. - * - * @param string $pagename Page name - * @param bool $reversed True to get backlinks - * @param bool $include_empty True to get empty pages - * @param string $sortby - * @param string $limit - * @param string $exclude Pages to exclude - * @param bool $want_relations - * - * FIXME: array or iterator? - * @return object A WikiDB_backend_iterator. - * - * Optimization: save request->_dbi->_iwpcache[] to avoid further iswikipage checks - * (linkExistingWikiWord or linkUnknownWikiWord) - * This is called on every page header GleanDescription, so we can store all the - * existing links. - * - * relations: $backend->get_links is responsible to add the relation to the pagehash - * as 'linkrelation' key as pagename. See WikiDB_PageIterator::next - * if (isset($next['linkrelation'])) - */ - function get_links($pagename, $reversed = true, $include_empty = false, - $sortby = '', $limit = '', $exclude = '', - $want_relations = false) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - - if ($reversed) - list($have, $want) = array('linkee', 'linker'); - else - list($have, $want) = array('linker', 'linkee'); - $orderby = $this->sortby($sortby, 'db', array('pagename')); - if ($orderby) $orderby = " ORDER BY $want." . $orderby; - if ($exclude) // array of pagenames - $exclude = " AND $want.pagename NOT IN " . $this->_sql_set($exclude); - else - $exclude = ''; - - $qpagename = $dbh->qstr($pagename); - // removed ref to FETCH_MODE in next line - $sql = "SELECT $want.id AS id, $want.pagename AS pagename, " - . ($want_relations ? " related.pagename as linkrelation" : " $want.hits AS hits") - . " FROM " - . (!$include_empty ? "$nonempty_tbl, " : '') - . " $page_tbl linkee, $page_tbl linker, $link_tbl " - . ($want_relations ? " JOIN $page_tbl related ON ($link_tbl.relation=related.id)" : '') - . " WHERE linkfrom=linker.id AND linkto=linkee.id" - . " AND $have.pagename=$qpagename" - . (!$include_empty ? " AND $nonempty_tbl.id=$want.id" : "") - //. " GROUP BY $want.id" - . $exclude - . $orderby; - if ($limit) { - // extract from,count from limit - list($offset, $count) = $this->limit($limit); - $result = $dbh->SelectLimit($sql, $count, $offset); - } else { - $result = $dbh->Execute($sql); - } - $fields = $this->links_field_list; - if ($want_relations) // instead of hits - $fields[2] = 'linkrelation'; - return new WikiDB_backend_ADODB_iter($this, $result, $fields); - } - - /* - * Find if a page links to another page - */ - function exists_link($pagename, $link, $reversed = false) - { - $dbh = &$this->_dbh; - extract($this->_table_names); - ... [truncated message content] |