2 rcs_id('$Id: ADODB_mysql.php,v 1.14 2005-04-01 14:32:44 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))";
46 // esp. needed for utf databases
47 if ($this->_serverinfo['version'] > 401.0) {
49 //http://dev.mysql.com/doc/mysql/en/charset-connection.html
50 if (strtolower($charset) == 'iso-8859-1') {
51 // mysql needs different names and doesn't resolve aliases
52 mysql_query("SET NAMES 'latin1'");
53 //mysql_query("SET CHARACTER SET latin1");
55 //SET NAMES 'latin1' or 'utf8'
56 mysql_query("SET NAMES '$charset'");
62 * Kill timed out processes. ( so far only called on about every 50-th save. )
65 if (empty($this->_dbparams['timeout'])) return;
66 $result = mysql_query("SHOW processlist");
67 while ($row = mysql_fetch_array($result)) {
68 if ($row["db"] == $this->_dsn['database']
69 and $row["User"] == $this->_dsn['username']
70 and $row["Time"] > $this->_dbparams['timeout']
71 and $row["Command"] == "Sleep")
73 $process_id = $row["Id"];
74 mysql_query("KILL $process_id");
85 foreach ($this->_table_names as $table) {
86 $dbh->Execute("OPTIMIZE TABLE $table");
92 * Lock tables. As fine-grained application lock, which locks only the same transaction
93 * (conflicting updates and edits), and as full table write lock.
95 * New: which tables as params,
96 * support nested locks via app locks
99 function _lock_tables($tables, $write_lock = true) {
100 if (!$tables) return;
102 $lock = join('-',$tables);
103 $result = $this->_dbh->GetRow("SELECT GET_LOCK('$lock',10)");
104 if (!$result or $result[0] == 0) {
105 trigger_error( "WARNING: Couldn't obtain application lock " . $lock . "\n<br />",
111 // if this is not enough:
112 $lock_type = $write_lock ? "WRITE" : "READ";
113 foreach ($this->_table_names as $key => $table) {
114 $locks[] = "$table $lock_type";
116 $this->_dbh->Execute("LOCK TABLES " . join(",", $locks));
122 * Support nested locks
124 function _unlock_tables($tables) {
126 $this->_dbh->Execute("UNLOCK TABLES");
130 $lock = join('-',$tables);
131 $result = $this->_dbh->Execute("SELECT RELEASE_LOCK('$lock')");
134 // if this is not enough:
135 $this->_dbh->Execute("UNLOCK TABLES");
139 function increaseHitCount($pagename) {
141 // Hits is the only thing we can update in a fast manner.
142 // Note that this will fail silently if the page does not
143 // have a record in the page table. Since it's just the
144 // hit count, who cares?
146 $dbh->Execute(sprintf("UPDATE LOW_PRIORITY %s SET hits=hits+1 WHERE pagename=%s %s",
147 $this->_table_names['page_tbl'],
148 $dbh->qstr($pagename),
149 ($this->_serverinfo['version'] >= 323.0) ? "LIMIT 1": "")
156 // (c-file-style: "gnu")
161 // c-hanging-comment-ender-p: nil
162 // indent-tabs-mode: nil