2 rcs_id('$Id: ADODB_mysql.php,v 1.10 2004-11-26 18:39:02 rurban Exp $');
4 require_once('lib/WikiDB/backend/ADODB.php');
7 * PROBLEM: mysql seems to be the simpliest (or most stupid) db on earth.
9 * Whenever a table is write-locked, you cannot even write to other unrelated
10 * tables. So it seems that we have to lock all tables!
11 * As workaround we try it with application locks, uniquely named locks,
12 * to prevent from concurrent writes of locks with the same name.
13 * The lock name is a strcat of the involved tables.
15 define('DO_APP_LOCK',true);
16 define('DO_FULL_LOCK',false);
19 * WikiDB layer for ADODB-mysql, called by lib/WikiDB/ADODB.php.
20 * Now with support for the newer adodb library, the adodb extension library
21 * and more database drivers.
22 * To use transactions use the mysqlt driver: "mysqlt:..."
24 * @author: Lawrence Akka, Reini Urban
26 class WikiDB_backend_ADODB_mysql
27 extends WikiDB_backend_ADODB
32 function WikiDB_backend_ADODB_mysql($dbparams) {
33 $this->WikiDB_backend_ADODB($dbparams);
35 $this->_serverinfo = $this->_dbh->ServerInfo();
36 if (!empty($this->_serverinfo['version'])) {
37 $arr = explode('.',$this->_serverinfo['version']);
38 $this->_serverinfo['version'] = (string)(($arr[0] * 100) + $arr[1]) . "." . (integer)$arr[2];
40 if ($this->_serverinfo['version'] < 323.0) {
41 // Older MySQL's don't have CASE WHEN ... END
42 $this->_expressions['maxmajor'] = "MAX(IF(minor_edit=0,version,0))";
43 $this->_expressions['maxminor'] = "MAX(IF(minor_edit<>0,version,0))";
48 * Kill timed out processes. ( so far only called on about every 50-th save. )
51 if (empty($this->_dbparams['timeout'])) return;
52 $result = mysql_query("SHOW processlist");
53 while ($row = mysql_fetch_array($result)) {
54 if ($row["db"] == $this->_dsn['database']
55 and $row["User"] == $this->_dsn['username']
56 and $row["Time"] > $this->_dbparams['timeout']
57 and $row["Command"] == "Sleep") {
58 $process_id = $row["Id"];
59 mysql_query("KILL $process_id");
70 foreach ($this->_table_names as $table) {
71 $dbh->Execute("OPTIMIZE TABLE $table");
77 * Lock tables. As fine-grained application lock, which locks only the same transaction
78 * (conflicting updates and edits), and as full table write lock.
80 * New: which tables as params,
81 * support nested locks via app locks
84 function _lock_tables($tables, $write_lock = true) {
87 $lock = join('-',$tables);
88 $result = $this->_dbh->GetRow("SELECT GET_LOCK('$lock',10)");
89 if (!$result or $result[0] == 0) {
90 trigger_error( "WARNING: Couldn't obtain application lock " . $lock . "\n<br />",
96 // if this is not enough:
97 $lock_type = $write_lock ? "WRITE" : "READ";
98 foreach ($this->_table_names as $key => $table) {
99 $locks[] = "$table $lock_type";
101 $this->_dbh->Execute("LOCK TABLES " . join(",", $locks));
107 * Support nested locks
109 function _unlock_tables($tables) {
111 $this->_dbh->Execute("UNLOCK TABLES");
115 $lock = join('-',$tables);
116 $result = $this->_dbh->Execute("SELECT RELEASE_LOCK('$lock')");
119 // if this is not enough:
120 $this->_dbh->Execute("UNLOCK TABLES");
124 function increaseHitCount($pagename) {
126 // Hits is the only thing we can update in a fast manner.
127 // Note that this will fail silently if the page does not
128 // have a record in the page table. Since it's just the
129 // hit count, who cares?
131 $dbh->Execute(sprintf("UPDATE LOW_PRIORITY %s SET hits=hits+1 WHERE pagename=%s %s",
132 $this->_table_names['page_tbl'],
133 $dbh->qstr($pagename),
134 ($this->_serverinfo['version'] >= 323.0) ? "LIMIT 1": ""
141 // (c-file-style: "gnu")
146 // c-hanging-comment-ender-p: nil
147 // indent-tabs-mode: nil