aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--boot.php23
-rw-r--r--include/dba.php436
-rw-r--r--index.php7
-rw-r--r--view/de/strings.php1
-rw-r--r--view/de/update_fail_eml.tpl12
-rw-r--r--view/update_fail_eml.tpl11
6 files changed, 302 insertions, 188 deletions
diff --git a/boot.php b/boot.php
index b1c378d34..c21cefa18 100644
--- a/boot.php
+++ b/boot.php
@@ -653,8 +653,31 @@ function check_config(&$a) {
// call the specific update
+ global $db;
+ try {
+ $db->beginTransaction();
$func = 'update_' . $x;
$func($a);
+ $db->commit();
+ } catch(Exception $ex) {
+ $db->rollback();
+ //send the administrator an e-mail
+ $email_tpl = get_intltext_template("update_fail_eml.tpl");
+ $email_tpl = replace_macros($email_tpl, array(
+ '$sitename' => $a->config['sitename'],
+ '$siteurl' => $a->get_baseurl(),
+ '$update' => $x,
+ '$error' => $ex->getMessage());
+ $subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
+
+ mail($email, $subject, $text,
+ 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
+ . 'Content-type: text/plain; charset=UTF-8' . "\n"
+ . 'Content-transfer-encoding: 8bit' );
+ //try the logger
+ logger('update failed: '.$ex->getMessage().EOL);
+ }
+
}
}
set_config('system','build', DB_UPDATE_VERSION);
diff --git a/include/dba.php b/include/dba.php
index 76cc0bc7b..cbf5922a7 100644
--- a/include/dba.php
+++ b/include/dba.php
@@ -8,189 +8,245 @@ require_once('include/datetime.php');
*
* For debugging, insert 'dbg(1);' anywhere in the program flow.
* dbg(0); will turn it off. Logging is performed at LOGGER_DATA level.
- * When logging, all binary info is converted to text and html entities are escaped so that
- * the debugging stream is safe to view within both terminals and web pages.
+ * When logging, all binary info is converted to
+ * text and html entities are escaped so that
+ * the debugging stream is safe to view
+ * within both terminals and web pages.
*
*/
-
-if(! class_exists('dba')) {
-class dba {
-
- private $debug = 0;
- private $db;
- public $mysqli = true;
- public $connected = false;
- public $error = false;
-
- function __construct($server,$user,$pass,$db,$install = false) {
-
- $server = trim($server);
- $user = trim($user);
- $pass = trim($pass);
- $db = trim($db);
-
- if (!(strlen($server) && strlen($user))){
- $this->connected = false;
- $this->db = null;
- return;
- }
-
- if($install) {
- if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
- if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
- $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
- $this->connected = false;
- $this->db = null;
- return;
- }
+
+if(! class_exists('dba')) {
+
+ class dba {
+
+ private $debug = 0;
+ private $db;
+ public $mysqli = true;
+ public $connected = false;
+ public $error = false;
+
+ function __construct($server,$user,$pass,$db,$install = false) {
+
+ $server = trim($server);
+ $user = trim($user);
+ $pass = trim($pass);
+ $db = trim($db);
+
+ //we need both, server and username, so fail if one is missing
+ if (!(strlen($server) && strlen($user))){
+ $this->connected = false;
+ $this->db = null;
+ throw new InvalidArgumentException(t("Server name of user name are missing. "));
}
- }
- if(class_exists('mysqli')) {
- $this->db = @new mysqli($server,$user,$pass,$db);
- if(! mysqli_connect_errno()) {
- $this->connected = true;
+ //when we are installing
+ if($install) {
+ if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
+ if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
+ $this->connected = false;
+ $this->db = null;
+ throw new InvalidArgumentException( t('Cannot locate DNS info for database server \'%s\''), $server);
+ }
+ }
}
- }
- else {
- $this->mysqli = false;
- $this->db = mysql_connect($server,$user,$pass);
- if($this->db && mysql_select_db($db,$this->db)) {
- $this->connected = true;
+
+ if(class_exists('mysqli')) {
+ $this->db = new mysqli($server,$user,$pass,$db);
+ if(NULL === $this->db->connect_error()) {
+ $this->connected = true;
+ } else {
+ throw new RuntimeException($this->db->connect_error());
+ }
+ } else {
+ $this->mysqli = false;
+ $this->db = mysql_connect($server,$user,$pass);
+ if($this->db && mysql_select_db($db,$this->db)) {
+ $this->connected = true;
+ } else {
+ throw new RuntimeException(mysql_error());
+ }
}
}
- if(! $this->connected) {
- $this->db = null;
- if(! $install)
- system_unavailable();
+
+ public function getdb() {
+ return $this->db;
}
- }
- public function getdb() {
- return $this->db;
- }
+ public function q($sql) {
- public function q($sql) {
-
- if((! $this->db) || (! $this->connected))
- return false;
-
- if($this->mysqli)
- $result = @$this->db->query($sql);
- else
- $result = @mysql_query($sql,$this->db);
+ if((! $this->db) || (! $this->connected)) {
+ throw new RuntimeException(t("There is no db connection. "));
+ }
- if($this->debug) {
+ if($this->mysqli) {
+ $result = $this->db->query($sql);
+ } else {
+ $result = mysql_query($sql,$this->db);
+ }
+
+ //on debug mode or fail, the query is written to the log.
+ //this won't work if logger can not read it's logging level
+ //from the db.
+ if($this->debug || FALSE === $result) {
+
+ $mesg = '';
+
+ if($result === false) {
+ $mesg = 'false '.$this->error();
+ } elseif($result === true) {
+ $mesg = 'true';
+ } else {
+ if($this->mysqli) {
+ $mesg = $result->num_rows . t(' results') . EOL;
+ } else {
+ $mesg = mysql_num_rows($result) . t(' results') . EOL;
+ }
+ }
- $mesg = '';
+ $str = 'SQL = ' . printable($sql) . EOL . t('SQL returned ') . $mesg . EOL;
- if($this->mysqli) {
- if($this->db->errno)
- logger('dba: ' . $this->db->error);
+
+ // If dbfail.out exists, we will write any failed calls directly to it,
+ // regardless of any logging that may or may nor be in effect.
+ // These usually indicate SQL syntax errors that need to be resolved.
+ if(file_exists('dbfail.out')) {
+ file_put_contents('dbfail.out', datetime_convert() . "\n" . $str . "\n", FILE_APPEND);
+ }
+ logger('dba: ' . $str );
+ if(FALSE===$result) {
+ throw new RuntimeException('dba: ' . $str);
+ }
}
- elseif(mysql_errno($this->db))
- logger('dba: ' . mysql_error($this->db));
-
- if($result === false)
- $mesg = 'false';
- elseif($result === true)
- $mesg = 'true';
- else {
- if($this->mysqli)
- $mesg = $result->num_rows . ' results' . EOL;
- else
- $mesg = mysql_num_rows($result) . ' results' . EOL;
+
+
+ if($result === true) {
+ return $result;
}
-
- $str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg . EOL;
- logger('dba: ' . $str );
- }
+ $r = array();
+ if($this->mysqli) {
+ if($result->num_rows) {
+ while($x = $result->fetch_array(MYSQLI_ASSOC)) {
+ $r[] = $x;
+ }
+ $result->free_result();
+ }
+ } else {
+ if(mysql_num_rows($result)) {
+ while($x = mysql_fetch_array($result, MYSQL_ASSOC)) {
+ $r[] = $x;
+ }
+ mysql_free_result($result);
+ }
+ }
- /**
- * If dbfail.out exists, we will write any failed calls directly to it,
- * regardless of any logging that may or may nor be in effect.
- * These usually indicate SQL syntax errors that need to be resolved.
- */
- if($result === false) {
- logger('dba: ' . printable($sql) . ' returned false.');
- if(file_exists('dbfail.out'))
- file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n", FILE_APPEND);
+ if($this->debug) {
+ logger('dba: ' . printable(print_r($r, true)));
+ }
+ return($r);
}
- if(($result === true) || ($result === false))
- return $result;
-
- $r = array();
- if($this->mysqli) {
- if($result->num_rows) {
- while($x = $result->fetch_array(MYSQLI_ASSOC))
- $r[] = $x;
- $result->free_result();
+ private function error() {
+ if($this->mysqli) {
+ return $this->db->error;
+ } else {
+ return mysql_error($this->db);
}
}
- else {
- if(mysql_num_rows($result)) {
- while($x = mysql_fetch_array($result, MYSQL_ASSOC))
- $r[] = $x;
- mysql_free_result($result);
+
+ public function beginTransaction() {
+ if($this->mysqli) {
+ return $this->db->autocommit(false);
+ } else {
+ //no transaction support in mysql module...
+ mysql_query('SET AUTOCOMMIT = 0;', $db);
+ }
+ }
+
+ public function rollback() {
+ if($this->mysqli) {
+ return $this->db->rollback();
+ } else {
+ //no transaction support in mysql module...
+ mysql_query('ROLLBACK;', $db);
}
+ $this->stopTransaction();
}
-
- if($this->debug)
- logger('dba: ' . printable(print_r($r, true)));
- return($r);
- }
-
- public function dbg($dbg) {
- $this->debug = $dbg;
- }
+ public function commit() {
+ if($this->mysqli) {
+ return $this->db->commit();
+ } else {
+ //no transaction support in mysql module...
+ mysql_query('COMMIT;', $db);
+ }
+ $this->stopTransaction();
+ }
+
+ private function stopTransaction() {
+ if($this->mysqli) {
+ return $this->db->autocommit(true);
+ } else {
+ //no transaction support in mysql module...
+ mysql_query('SET AUTOCOMMIT = 1;', $db);
+ }
+ }
+
+ public function dbg($dbg) {
+ $this->debug = $dbg;
+ }
- public function escape($str) {
- if($this->db && $this->connected) {
- if($this->mysqli)
- return @$this->db->real_escape_string($str);
- else
- return @mysql_real_escape_string($str,$this->db);
+ public function escape($str) {
+ if($this->db && $this->connected) {
+ if($this->mysqli) {
+ return $this->db->real_escape_string($str);
+ } else {
+ return mysql_real_escape_string($str,$this->db);
+ }
+ }
}
- }
- function __destruct() {
- if ($this->db)
- if($this->mysqli)
- $this->db->close();
- else
+ function __destruct() {
+ if ($this->db) {
+ if($this->mysqli) {
+ $this->db->close();
+ }
+ } else {
mysql_close($this->db);
+ }
+ }
}
-}}
+}
if(! function_exists('printable')) {
-function printable($s) {
- $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
- $s = str_replace("\x00",'.',$s);
- if(x($_SERVER,'SERVER_NAME'))
- $s = escape_tags($s);
- return $s;
-}}
+ function printable($s) {
+ $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
+ $s = str_replace("\x00",'.',$s);
+ if(x($_SERVER,'SERVER_NAME'))
+ $s = escape_tags($s);
+ return $s;
+ }
+}
// Procedural functions
-if(! function_exists('dbg')) {
-function dbg($state) {
- global $db;
- if($db)
- $db->dbg($state);
-}}
+if(! function_exists('dbg')) {
+ function dbg($state) {
+ global $db;
+ if($db)
+ $db->dbg($state);
+ }
+}
-if(! function_exists('dbesc')) {
-function dbesc($str) {
- global $db;
- if($db && $db->connected)
- return($db->escape($str));
- else
- return(str_replace("'","\\'",$str));
-}}
+if(! function_exists('dbesc')) {
+ function dbesc($str) {
+ global $db;
+ if($db && $db->connected)
+ return($db->escape($str));
+ else
+ return(str_replace("'","\\'",$str));
+ }
+}
@@ -199,30 +255,31 @@ function dbesc($str) {
// Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
// 'user', 1);
-if(! function_exists('q')) {
-function q($sql) {
+if(! function_exists('q')) {
+ function q($sql) {
- global $db;
- $args = func_get_args();
- unset($args[0]);
+ global $db;
+ $args = func_get_args();
+ unset($args[0]);
- if($db && $db->connected) {
- $stmt = vsprintf($sql,$args);
- if($stmt === false)
- logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true));
- return $db->q($stmt);
- }
+ if($db && $db->connected) {
+ $stmt = vsprintf($sql,$args);
+ if($stmt === false)
+ logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true));
+ return $db->q($stmt);
+ }
- /**
- *
- * This will happen occasionally trying to store the
- * session data after abnormal program termination
- *
- */
- logger('dba: no database: ' . print_r($args,true));
- return false;
+ /**
+ *
+ * This will happen occasionally trying to store the
+ * session data after abnormal program termination
+ *
+ */
+ logger('dba: no database: ' . print_r($args,true));
+ return false;
-}}
+ }
+}
/**
*
@@ -230,36 +287,39 @@ function q($sql) {
*
*/
-if(! function_exists('dbq')) {
-function dbq($sql) {
+if(! function_exists('dbq')) {
+ function dbq($sql) {
- global $db;
- if($db && $db->connected)
- $ret = $db->q($sql);
- else
- $ret = false;
- return $ret;
-}}
+ global $db;
+ if($db && $db->connected)
+ $ret = $db->q($sql);
+ else
+ $ret = false;
+ return $ret;
+ }
+}
-// Caller is responsible for ensuring that any integer arguments to
+// Caller is responsible for ensuring that any integer arguments to
// dbesc_array are actually integers and not malformed strings containing
-// SQL injection vectors. All integer array elements should be specifically
-// cast to int to avoid trouble.
+// SQL injection vectors. All integer array elements should be specifically
+// cast to int to avoid trouble.
if(! function_exists('dbesc_array_cb')) {
-function dbesc_array_cb(&$item, $key) {
- if(is_string($item))
- $item = dbesc($item);
-}}
+ function dbesc_array_cb(&$item, $key) {
+ if(is_string($item))
+ $item = dbesc($item);
+ }
+}
if(! function_exists('dbesc_array')) {
-function dbesc_array(&$arr) {
- if(is_array($arr) && count($arr)) {
- array_walk($arr,'dbesc_array_cb');
+ function dbesc_array(&$arr) {
+ if(is_array($arr) && count($arr)) {
+ array_walk($arr,'dbesc_array_cb');
+ }
}
-}}
+}
diff --git a/index.php b/index.php
index 1cb16778a..0cf74365c 100644
--- a/index.php
+++ b/index.php
@@ -11,6 +11,7 @@
* bootstrap the application
*
*/
+try {
require_once('boot.php');
@@ -370,3 +371,9 @@ else
session_write_close();
exit;
+} catch(Exception $ex) {
+// it may fail because logger uses the db,
+// but give it a try:
+logger('exception caught at index.php: '.$ex->getMessage());
+system_unavailable();
+} \ No newline at end of file
diff --git a/view/de/strings.php b/view/de/strings.php
index 28567396b..5339d8a12 100644
--- a/view/de/strings.php
+++ b/view/de/strings.php
@@ -1511,3 +1511,4 @@ $a->strings["[today]"] = "[heute]";
$a->strings["Event Reminders"] = "Veranstaltungserinnerungen";
$a->strings["Events this week:"] = "Veranstaltungen diese Woche";
$a->strings["[No description]"] = "[keine Beschreibung]";
+$a->strings['Update Error at %s'] = 'Fehler beim Updaten von %s';
diff --git a/view/de/update_fail_eml.tpl b/view/de/update_fail_eml.tpl
new file mode 100644
index 000000000..26be1786f
--- /dev/null
+++ b/view/de/update_fail_eml.tpl
@@ -0,0 +1,12 @@
+Hey,
+Ich bin's, $sitename.
+Die Friendica-Entwickler haben gerade Update $update freigegeben,
+aber als ich es installieren wollte, ist irgendetwas schief gegangen.
+Das sollte schnell repariert werden und alleine schaffe ich es nicht.
+Wende dich bitte an einen Friendica-Entwickler, wenn du mir nicht selbst helfen kannst.
+Meine Datenbank könnte ziemlich durcheinander sein.
+
+Die Fehlermeldung ist '$error'.
+
+Tut mir leid,
+dein Friendica Server unter $siteurl \ No newline at end of file
diff --git a/view/update_fail_eml.tpl b/view/update_fail_eml.tpl
new file mode 100644
index 000000000..f68a3dece
--- /dev/null
+++ b/view/update_fail_eml.tpl
@@ -0,0 +1,11 @@
+Hey,
+I'm $sitename.
+The friendica developers released update $update recently,
+but when I tried to install it, something went terribly wrong.
+This needs to be fixed soon and I can't do it alone. Please contact a
+friendica developer if you can not help me on your own. My database might be invalid.
+
+The error message is '$error'.
+
+I'm sorry,
+your friendica server at $siteurl \ No newline at end of file