diff --git a/html/inc/boinc_db.inc b/html/inc/boinc_db.inc
index 63ca43d5b44..0499cee896a 100644
--- a/html/inc/boinc_db.inc
+++ b/html/inc/boinc_db.inc
@@ -26,120 +26,94 @@ incs();
class BoincDb extends DbConn {
static $instance;
-
- // connect to the database (possibly to a read-only replica)
- // NOTE: choice of replica can be made only at the page level.
- // If there's a page that's guaranteed to do only reads, put
- // BoincDb::get(true);
- // at the top of it.
- //
- // Specify a $fallback_mode that is used when $readonly is true:
- // 0: default, use db_user if no replica_db_user is specified,
- // first try replica_db_host (if specified) then db_host
- // 1: only use replica_db_user, first try replica_db_host then db_host
- // 2: only use replica_db_user, only try replica_db_host
- // can be set projectwide using
+ static $dbnum = 0;
+
+ // A project can have one or more databases:
+ // DB 0:
+ // the main DB; read/write
+ // identified in config file by db_host, db_name, db_user, db_passwd
+ // db_host defaults to localhost
+ // DB 1:
+ // read-only replica; identified by
+ // replica_db_host/name/user/passwd (must include all)
+ // DB 2:
+ // read-only replica; identified by
+ // replica2_db_host/name/user/passwd (must include all)
+ // ... and potentially more
+
+ // connect to DB $dbnum (0, 1, ...)
+ // If the requested DB doesn't exist or connection fails, connect to DB 0.
+ // Set self::$instance; no return value
//
- static function get_aux($readonly, $fallback_mode = 0) {
- $config = get_config();
- $user = parse_config($config, '');
- $passwd = parse_config($config, '');
- $host = parse_config($config, '');
- $replica_host = parse_config($config, '');
- $name = parse_config($config, '');
- $fm = parse_config($config, '');
- if ($fm) {
- // override parameter with config.xml setting
- $fallback_mode = $fm;
- }
- if ($host == null) {
- $host = "localhost";
- }
+ static function get_aux($dbnum) {
$instance = new DbConn();
- if ($readonly) {
- if (($fallback_mode > 0) && (!$replica_host)) {
- error_log("BoincDb::get_aux(): required for \$fallback_mode > 0 (giving up)");
- $instance = null;
- self::$instance = $instance;
- return $instance;
- }
- $u = parse_config($config, '');
- $p = parse_config($config, '');
- $n = parse_config($config, '');
- if (($fallback_mode > 0) && (!$u || !$p || !$n)) {
- error_log("BoincDb::get_aux(): required for \$fallback_mode > 0 (giving up)");
- $instance = null;
- self::$instance = $instance;
- return $instance;
- } else {
- // use replica user if given or use normal user for $fallback_mode == 0
- if ($u) $user = $u;
- if ($p) $passwd = $p;
- if ($n) $name = $n;
- }
- // skip this block if no $replica_host is specified for $fallback_mode == 0
- if ($replica_host) {
- $retval = $instance->init_conn(
- $user, $passwd, $replica_host, $name, true
- );
+ self::$instance = null;
+ $config = get_config();
+ if ($dbnum) {
+ $r = $dbnum==1?'':strval($dbnum);
+ $host = parse_config($config, sprintf('', $r));
+ $name = parse_config($config, sprintf('', $r));
+ $user = parse_config($config, sprintf('', $r));
+ $passwd = parse_config($config, sprintf('', $r));
+ if ($host && $name && $user && $passwd) {
+ $retval = $instance->init_conn($user, $passwd, $host, $name);
if ($retval) {
- // needed for places where we do direct queries
- if (!$instance->do_query("use $name")) {
- error_log("BoincDb::get_aux(): Couldn't select database $name on $replica_host (giving up)");
- $instance = null;
- }
self::$instance = $instance;
- return $instance;
- } elseif ($fallback_mode == 2) {
- // no fallback to master in this case
- error_log("BoincDb::get_aux(): Couldn't connect to $user@$replica_host (giving up)");
- $instance = null;
- self::$instance = $instance;
- return $instance;
- } else {
- error_log("BoincDb::get_aux(): Couldn't connect to $user@$replica_host (trying $user@$host next)");
+ return;
}
}
+ // if can't connect to replica, fall through and try DB 0
}
- $retval = $instance->init_conn($user, $passwd, $host, $name, false);
- if (!$retval) {
- $instance = null;
- error_log("BoincDb::get_aux(): Couldn't connect to $user@$host (giving up)");
- } else {
- // needed for places where we do direct queries
- if (!$instance->do_query("use $name")) {
- error_log("BoincDb::get_aux(): Couldn't select database $name on $host (giving up)");
- $instance = null;
- }
+ $host = parse_config($config, '');
+ if (!$host) $host = 'localhost';
+ $user = parse_config($config, '');
+ $name = parse_config($config, '');
+ $passwd = parse_config($config, '');
+ if (!$name || !$user || !$passwd) {
+ error_log("BoincDb::get_aux(): must specify DB name, user, passwd");
+ return;
}
- self::$instance = $instance;
- return $instance;
+ $retval = $instance->init_conn($user, $passwd, $host, $name);
+ if ($retval) {
+ self::$instance = $instance;
+ return;
+ }
+ error_log("BoincDb::get_aux(): Couldn't connect to DB $dbnum");
}
- // same, but
+ // connect to DB $dbnum, but first:
// 1) check for a cached connection
// 2) check whether the "stop_web" trigger file is present
//
- static function get($readonly = false, $fallback_mode = 0) {
+ // If there's a page that's guaranteed to do only reads, put
+ // BoincDb::get(true);
+ // at the top of it.
+ //
+ // Note: true == 1.
+ // You can also use 2, 3... to select other replicas
+ //
+ static function get($dbnum = 0) {
global $generating_xml;
- if (!isset(self::$instance)) {
- if (web_stopped()) {
- if ($generating_xml) {
- xml_error(-183, "project down for maintenance");
- } else {
- show_project_down();
- }
- }
- self::get_aux($readonly, $fallback_mode);
- if (!self::$instance) {
- if ($generating_xml) {
- xml_error(-138, "Can't connect to database");
- } else {
- error_page("Can't connect to database");
- }
+ if (isset(self::$instance) && intval(self::$dbnum) == intval($dbnum)) {
+ return self::$instance;
+ }
+ if (web_stopped()) {
+ if ($generating_xml) {
+ xml_error(-183, "project down for maintenance");
+ } else {
+ show_project_down();
}
}
- return self::$instance;
+ self::get_aux($dbnum);
+ if (self::$instance) {
+ self::$dbnum = $dbnum;
+ return self::$instance;
+ }
+ if ($generating_xml) {
+ xml_error(-138, "Can't connect to database");
+ } else {
+ error_page("Can't connect to database");
+ }
}
static function escape_string($string) {
diff --git a/html/inc/db.inc b/html/inc/db.inc
index 0238e80475d..1c51d3b5b03 100644
--- a/html/inc/db.inc
+++ b/html/inc/db.inc
@@ -24,20 +24,7 @@ require_once("../inc/util_basic.inc");
// DEPRECATED; use boinc_db.inc instead.
// TODO: replace calls to these functions
-// use mysqli if available,
-// but let projects not use it if they want
-// (put in config.xml)
-//
-if (parse_bool(get_config(), "no_mysqli")) {
- define("MYSQLI", false);
-} else {
- if (class_exists("mysqli")) {
- define("MYSQLI", true);
- $mysqli = null;
- } else {
- define("MYSQLI", false);
- }
-}
+define("MYSQLI", true);
if (MYSQLI) {
function _mysql_connect($host, $user, $pass, $dbname) {
diff --git a/html/inc/db_conn.inc b/html/inc/db_conn.inc
index 7eb0fb70d06..11d2573b063 100644
--- a/html/inc/db_conn.inc
+++ b/html/inc/db_conn.inc
@@ -24,37 +24,33 @@ require_once("../inc/db.inc");
class DbConn {
var $db_conn;
var $db_name;
- var $readonly;
- function init_conn($user, $passwd, $host, $name, $readonly) {
- if (MYSQLI) {
- $x = explode(":", $host);
- if (sizeof($x)>1) {
- $host = $x[0];
- $port = $x[1];
- } else {
- $port = null;
- }
- //if (version_compare(PHP_VERSION, '5.3.0') < 0) {
- if (1) { // don't use persistent connections for now
- $this->db_conn = @new mysqli($host, $user, $passwd, $name, $port);
- } else {
- $this->db_conn = @new mysqli("p:".$host, $user, $passwd, $name, $port);
- }
- // mysqli returns an object even if the connection is not established
- if (mysqli_connect_error()) {
- return false;
- }
- global $mysqli;
- $mysqli = $this->db_conn;
+ function init_conn($user, $passwd, $host, $name) {
+ $x = explode(":", $host);
+ if (sizeof($x)>1) {
+ $host = $x[0];
+ $port = $x[1];
+ } else {
+ $port = null;
+ }
+ if (1) { // don't use persistent connections for now
+ $this->db_conn = @new mysqli(
+ $host, $user, $passwd, $name, $port
+ );
} else {
- $this->db_conn = @mysql_pconnect($host, $user, $passwd);
+ $this->db_conn = @new mysqli(
+ 'p:'.$host, $user, $passwd, $name, $port
+ );
+ }
+ if (mysqli_connect_error()) {
+ return false;
}
+ global $mysqli;
+ $mysqli = $this->db_conn;
if (!$this->db_conn) {
return false;
}
$this->db_name = $name;
- $this->readonly = $readonly;
return true;
}
@@ -65,11 +61,7 @@ class DbConn {
global $generating_xml;
$q = str_replace('DBNAME', $this->db_name, $q);
//echo "query: $q
\n";
- if (MYSQLI) {
- $ret = $this->db_conn->query($q);
- } else {
- $ret = mysql_query($q, $this->db_conn);
- }
+ $ret = $this->db_conn->query($q);
if (!$ret) {
if (!$generating_xml) {
echo "Database Error
\n";
@@ -85,11 +77,7 @@ class DbConn {
// # rows affected by last query
//
function affected_rows() {
- if (MYSQLI) {
- return $this->db_conn->affected_rows;
- } else {
- return mysql_affected_rows($this->db_conn);
- }
+ return $this->db_conn->affected_rows;
}
function get_list($table1, $table2, $joinfield1, $joinfield2, $classname, $fields, $where_clause, $order_clause, $limit) {
@@ -97,17 +85,10 @@ class DbConn {
$result = $this->do_query($query);
if (!$result) return null;
$x = array();
- if (MYSQLI) {
- while ($obj = $result->fetch_object($classname)) {
- $x[] = $obj;
- }
- $result->free();
- } else {
- while ($obj = mysql_fetch_object($result, $classname)) {
- $x[] = $obj;
- }
- mysql_free_result($result);
+ while ($obj = $result->fetch_object($classname)) {
+ $x[] = $obj;
}
+ $result->free();
return $x;
}
@@ -117,13 +98,8 @@ class DbConn {
if (!$result) {
return null;
}
- if (MYSQLI) {
- $obj = $result->fetch_object($classname);
- $result->free();
- } else {
- $obj = mysql_fetch_object($result, $classname);
- mysql_free_result($result);
- }
+ $obj = $result->fetch_object($classname);
+ $result->free();
return $obj;
}
@@ -140,17 +116,10 @@ class DbConn {
$result = $this->do_query($query);
if (!$result) return null;
$x = array();
- if (MYSQLI) {
- while ($obj = $result->fetch_object($classname)) {
- $x[] = $obj;
- }
- $result->free();
- } else {
- while ($obj = mysql_fetch_object($result, $classname)) {
- $x[] = $obj;
- }
- mysql_free_result($result);
+ while ($obj = $result->fetch_object($classname)) {
+ $x[] = $obj;
}
+ $result->free();
return $x;
}
@@ -192,35 +161,21 @@ class DbConn {
return $this->do_query($query);
}
function insert_id() {
- if (MYSQLI) {
- return $this->db_conn->insert_id;
- } else {
- return mysql_insert_id($this->db_conn);
- }
+ return $this->db_conn->insert_id;
}
function get_int($query, $field) {
$result = $this->do_query($query);
if (!$result) error_page("database error on query $query");
- if (MYSQLI) {
- $x = $result->fetch_object("StdClass");
- $result->free();
- } else {
- $x = mysql_fetch_object($result);
- mysql_free_result($result);
- }
+ $x = $result->fetch_object("StdClass");
+ $result->free();
if ($x) return $x->$field;
return false;
}
function get_double($query, $field) {
$result = $this->do_query($query);
if (!$result) error_page("database error on query $query");
- if (MYSQLI) {
- $x = $result->fetch_object("StdClass");
- $result->free();
- } else {
- $x = mysql_fetch_object($result);
- mysql_free_result($result);
- }
+ $x = $result->fetch_object("StdClass");
+ $result->free();
if ($x) return (double)$x->$field;
return false;
}
@@ -248,25 +203,13 @@ class DbConn {
return $this->do_query($query);
}
function base_escape_string($string) {
- if (MYSQLI) {
- return $this->db_conn->escape_string($string);
- } else {
- return mysql_real_escape_string($string);
- }
+ return $this->db_conn->escape_string($string);
}
function base_error() {
- if (MYSQLI) {
- return $this->db_conn->error;
- } else {
- return mysql_error($this->db_conn);
- }
+ return $this->db_conn->error;
}
function base_errno() {
- if (MYSQLI) {
- return $this->db_conn->errno;
- } else {
- return mysql_errno($this->db_conn);
- }
+ return $this->db_conn->errno;
}
function table_exists($table_name) {
$result = $this->do_query("show tables from DBNAME like '$table_name'");