diff --git a/html/inc/boinc_db.inc b/html/inc/boinc_db.inc
index 79e0eb5a03..7231d36377 100644
--- a/html/inc/boinc_db.inc
+++ b/html/inc/boinc_db.inc
@@ -29,38 +29,84 @@ class BoincDb extends DbConn {
// BoincDb::get(true);
// at the top of it.
//
- static function get_aux($readonly) {
+ // 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 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";
}
$instance = new DbConn();
- if ($readonly && $replica_host) {
- $x = parse_config($config, '');
- if ($x) $user = $x;
- $x = parse_config($config, '');
- if ($x) $passwd = $x;
- $x = parse_config($config, '');
- if ($x) $name = $x;
- $retval = $instance->init_conn(
- $user, $passwd, $replica_host, $name, true
- );
- if ($retval) {
+ 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
+ );
+ 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)");
+ }
+ }
}
$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 {
- $instance->do_query("use $name");
- // needed for places where we do direct queries
+ // 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;
+ }
}
self::$instance = $instance;
return $instance;
@@ -70,7 +116,7 @@ class BoincDb extends DbConn {
// 1) check for a cached connection
// 2) check whether the "stop_web" trigger file is present
//
- static function get($readonly = false) {
+ static function get($readonly = false, $fallback_mode = 0) {
global $generating_xml;
if (!isset(self::$instance)) {
if (web_stopped()) {
@@ -83,7 +129,7 @@ class BoincDb extends DbConn {
exit;
}
}
- self::get_aux($readonly);
+ self::get_aux($readonly, $fallback_mode);
if (!self::$instance) {
if ($generating_xml) {
xml_error(-138, "the project's database server is down");