mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 07:53:39 +01:00
* Setup/API: improved diagnostics about db connection problem and not installed EGroupware
- removed deprecated egw_db->Halt_On_Error handling in favor of just exceptions - added a couple of exceptions extending egw_exception_db to be able to detect different problem areas - fixed setup to use / catch exceptions - new egw_exception_db_setup displays link to setup below exception message, to cope with no longer allowed html in exception messages
This commit is contained in:
parent
8703b9a8e8
commit
93710e09e1
@ -90,30 +90,32 @@ class egw extends egw_minimal
|
||||
// check if eGW is already setup, if not redirect to setup/
|
||||
try {
|
||||
$this->db->connect();
|
||||
if (!($num_config = $this->db->select(config::TABLE,'COUNT(config_name)',false,__LINE__,__FILE__)->fetchColumn()))
|
||||
{
|
||||
$num_config = $this->db->select(config::TABLE,'COUNT(config_name)',false,__LINE__,__FILE__)->fetchColumn();
|
||||
}
|
||||
catch(egw_exception_db_connection $e) {
|
||||
// ignore exception, get handled below
|
||||
}
|
||||
catch(egw_exception_db_invalid_sql $e1) {
|
||||
try {
|
||||
$phpgw_config = $this->db->select('phpgw_config','COUNT(config_name)',false,__LINE__,__FILE__)->fetchColumn();
|
||||
}
|
||||
catch (egw_exception_db_invalid_sql $e2) {
|
||||
// ignor error, get handled below
|
||||
}
|
||||
catch(Exception $e) {
|
||||
//echo "<pre>Connection to DB failed (".$e->getMessage().")!\n".$e->getTraceAsString();
|
||||
}
|
||||
if ($e || !$num_config)
|
||||
if (!$num_config)
|
||||
{
|
||||
$setup_dir = str_replace(array('home/index.php','index.php'),'setup/',$_SERVER['PHP_SELF']);
|
||||
|
||||
// we check for the old table too, to not scare updating users ;-)
|
||||
if ($phpgw_config)
|
||||
{
|
||||
throw new Exception('<center><b>Fatal Error:</b> You need to <a href="' . $setup_dir .
|
||||
'">update eGroupWare</a> before you can continue using it.</center>',999);
|
||||
throw new Exception('You need to update EGroupware before you can continue using it.',999);
|
||||
}
|
||||
else
|
||||
if ($e)
|
||||
{
|
||||
throw new Exception('<center><b>Fatal Error:</b> It appears that you have not created the database tables for '
|
||||
.'eGroupWare. Click <a href="' . $setup_dir . '">here</a> to run setup.</center>',999);
|
||||
throw new egw_exception_db_setup('Connection with '.$e->getMessage()."\n\n".
|
||||
'Maybe you not created a database for EGroupware yet.',999);
|
||||
}
|
||||
exit;
|
||||
throw new egw_exception_db_setup('It appears that you have not created the database tables for EGroupware.',999);
|
||||
}
|
||||
// Set the DB's client charset if a system-charset is set and some other values needed by egw_cache (used in config::read)
|
||||
foreach($GLOBALS['egw_info']['server']['system_charset'] = $this->db->select(config::TABLE,'config_name,config_value',array(
|
||||
@ -213,7 +215,7 @@ class egw extends egw_minimal
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup2 funcontion needs to be called after unserializing the egw-object
|
||||
* wakeup2 function needs to be called after unserializing the egw-object
|
||||
*
|
||||
* It adapts the restored object/enviroment to the changed (current) application / page-request
|
||||
*
|
||||
|
@ -107,12 +107,6 @@ class egw_db
|
||||
*/
|
||||
var $Debug = 0;
|
||||
|
||||
/**
|
||||
* @deprecated use exceptions (try/catch block) to handle failed connections or sql errors
|
||||
* @var string $Halt_On_Error "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore errror, but spit a warning)
|
||||
*/
|
||||
var $Halt_On_Error = 'yes';
|
||||
|
||||
/**
|
||||
* @var array $Record current record
|
||||
*/
|
||||
@ -400,8 +394,7 @@ class egw_db
|
||||
{
|
||||
if (!check_load_extension($php_extension))
|
||||
{
|
||||
$this->halt("Necessary php database support for $this->Type (".PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX.") not loaded and can't be loaded, exiting !!!");
|
||||
return null; // in case error-reporting = 'no'
|
||||
throw new egw_exception_db_connection("Necessary php database support for $this->Type (".PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX.") not loaded and can't be loaded, exiting !!!");
|
||||
}
|
||||
if (!isset($GLOBALS['egw']->ADOdb)) // use the global object to store the connection
|
||||
{
|
||||
@ -414,8 +407,7 @@ class egw_db
|
||||
$this->Link_ID = ADONewConnection($type);
|
||||
if (!$this->Link_ID)
|
||||
{
|
||||
$this->halt("No ADOdb support for '$type' ($this->Type) !!!");
|
||||
return null; // in case error-reporting = 'no'
|
||||
throw new egw_exception_db_connection("No ADOdb support for '$type' ($this->Type) !!!");
|
||||
}
|
||||
$connect = $GLOBALS['egw_info']['server']['db_persistent'] ? 'PConnect' : 'Connect';
|
||||
if (($Ok = $this->Link_ID->$connect($Host, $User, $Password)))
|
||||
@ -430,8 +422,7 @@ class egw_db
|
||||
if (!$Ok)
|
||||
{
|
||||
$Host = preg_replace('/password=[^ ]+/','password=$Password',$Host); // eg. postgres dsn contains password
|
||||
$this->halt("ADOdb::$connect($Host, $User, \$Password, $Database) failed.");
|
||||
return null; // in case error-reporting = 'no'
|
||||
throw new egw_exception_db_connection("ADOdb::$connect($Host, $User, \$Password, $Database) failed.");
|
||||
}
|
||||
if ($this->Debug)
|
||||
{
|
||||
@ -671,9 +662,8 @@ class egw_db
|
||||
}
|
||||
if (!$this->Query_ID)
|
||||
{
|
||||
$this->halt("Invalid SQL: ".(is_array($Query_String)?$Query_String[0]:$Query_String).
|
||||
($inputarr ? "<br>Parameters: '".implode("','",$inputarr)."'":''),
|
||||
$line, $file);
|
||||
throw new egw_exception_db_invalid_sql("Invalid SQL: ".(is_array($Query_String)?$Query_String[0]:$Query_String).
|
||||
($inputarr ? "<br>Parameters: '".implode("','",$inputarr)."'":''));
|
||||
}
|
||||
return $this->Query_ID;
|
||||
}
|
||||
@ -707,8 +697,7 @@ class egw_db
|
||||
{
|
||||
if (!$this->Query_ID)
|
||||
{
|
||||
$this->halt('next_record called with no query pending.');
|
||||
return 0;
|
||||
throw new egw_exception_db('next_record called with no query pending.');
|
||||
}
|
||||
if ($this->Row) // first row is already fetched
|
||||
{
|
||||
@ -763,10 +752,7 @@ class egw_db
|
||||
{
|
||||
if (!$this->Query_ID || !$this->Query_ID->Move($this->Row = $pos))
|
||||
{
|
||||
$this->halt("seek($pos) failed: resultset has " . $this->num_rows() . " rows");
|
||||
$this->Query_ID->Move( $this->num_rows() );
|
||||
$this->Row = $this->num_rows();
|
||||
return False;
|
||||
throw new egw_exception_db("seek($pos) failed: resultset has " . $this->num_rows() . " rows");
|
||||
}
|
||||
return True;
|
||||
}
|
||||
@ -973,65 +959,6 @@ class egw_db
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler
|
||||
*
|
||||
* @param string $msg error message
|
||||
* @param int $line line of calling method/function (optional)
|
||||
* @param string $file file of calling method/function (optional)
|
||||
*/
|
||||
function halt($msg, $line = '', $file = '')
|
||||
{
|
||||
if ($this->Link_ID) // only if we have a link, else infinite loop
|
||||
{
|
||||
$this->Error = $this->Link_ID->ErrorMsg(); // need to be BEFORE unlock,
|
||||
$this->Errno = $this->Link_ID->ErrorNo(); // else we get its error or none
|
||||
|
||||
$this->unlock(); /* Just in case there is a table currently locked */
|
||||
}
|
||||
if ($this->Halt_On_Error == "no")
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ($this->Halt_On_Error == 'yes')
|
||||
{
|
||||
throw new egw_exception_db($msg.($this->Error?":\n".$this->Error:''),$this->Errno);
|
||||
}
|
||||
$this->haltmsg($msg);
|
||||
|
||||
if ($file)
|
||||
{
|
||||
printf("<br /><b>File:</b> %s",$file);
|
||||
}
|
||||
if ($line)
|
||||
{
|
||||
printf("<br /><b>Line:</b> %s",$line);
|
||||
}
|
||||
printf("<br /><b>Function:</b> %s</p>\n",function_backtrace(2));
|
||||
|
||||
if ($this->Halt_On_Error != "report")
|
||||
{
|
||||
echo "<p><b>Session halted.</b></p>";
|
||||
if (is_object($GLOBALS['egw']->common))
|
||||
{
|
||||
$GLOBALS['egw']->common->egw_exit(True);
|
||||
}
|
||||
else // happens eg. in setup
|
||||
{
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function haltmsg($msg)
|
||||
{
|
||||
printf("<p><b>Database error:</b> %s<br>\n", $msg);
|
||||
if (($this->Errno || $this->Error) && $this->Error != "()")
|
||||
{
|
||||
printf("<b>$this->Type Error</b>: %s (%s)<br>\n",$this->Errno,$this->Error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description of a table
|
||||
*
|
||||
@ -1061,7 +988,6 @@ class egw_db
|
||||
if($column->primary_key) $flags .= "primary_key ";
|
||||
if($column->binary) $flags .= "binary ";
|
||||
|
||||
// _debug_array($column);
|
||||
$metadata[$i] = array(
|
||||
'table' => $table,
|
||||
'name' => $column->name,
|
||||
@ -1523,8 +1449,7 @@ class egw_db
|
||||
|
||||
if (!is_int($key) && is_array($column_definitions) && !isset($column_definitions[$key]))
|
||||
{
|
||||
// give a warning that we have no column-type
|
||||
$this->halt("db::column_data_implode('$glue',".print_r($array,True).",'$use_key',".print_r($only,True).",<pre>".print_r($column_definitions,True)."</pre><b>nothing known about column '$key'!</b>");
|
||||
throw new egw_exception_db_invalid_sql("db::column_data_implode('$glue',".print_r($array,True).",'$use_key',".print_r($only,True).",<pre>".print_r($column_definitions,True)."</pre><b>nothing known about column '$key'!</b>");
|
||||
}
|
||||
$column_type = is_array($column_definitions) ? @$column_definitions[$key]['type'] : False;
|
||||
$not_null = is_array($column_definitions) && isset($column_definitions[$key]['nullable']) ? !$column_definitions[$key]['nullable'] : false;
|
||||
@ -1912,7 +1837,7 @@ class egw_db
|
||||
{
|
||||
$ret = $this->Link_ID->UpdateBlob($table,$col,$val,$where,$table_def['fd'][$col]['type'] == 'blob' ? 'BLOB' : 'CLOB');
|
||||
if ($this->Debug) echo "<p>adodb::UpdateBlob('$table','$col','$val','$where') = '$ret'</p>\n";
|
||||
if (!$ret) $this->halt("Error in UpdateBlob($table,$col,\$val,$where)",$line,$file);
|
||||
if (!$ret) throw new egw_exception_db_invalid_sql("Error in UpdateBlob($table,$col,\$val,$where)",$line,$file);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
|
@ -138,8 +138,7 @@ class egw_exception_wrong_parameter extends egw_exception_assertion_failed { }
|
||||
class egw_exception_wrong_userinput extends egw_exception_assertion_failed { }
|
||||
|
||||
/**
|
||||
* Exceptions thrown by the egw_db class
|
||||
*
|
||||
* Exception thrown by the egw_db class for everything not covered by extended classed below
|
||||
*/
|
||||
class egw_exception_db extends egw_exception
|
||||
{
|
||||
@ -159,6 +158,25 @@ class egw_exception_db extends egw_exception
|
||||
|
||||
/**
|
||||
* Storing the row violates a unique key constrain
|
||||
*
|
||||
*/
|
||||
class egw_exception_db_not_unique extends egw_exception_db { }
|
||||
|
||||
/**
|
||||
* Can not connect to database: eg. database down, wrong host, name or credentials
|
||||
*/
|
||||
class egw_exception_db_connection extends egw_exception_db { }
|
||||
|
||||
/**
|
||||
* PHP lackst support for configured database type
|
||||
*/
|
||||
class egw_exception_db_support extends egw_exception_db { }
|
||||
|
||||
/**
|
||||
* Classic invalid SQL error
|
||||
*/
|
||||
class egw_exception_db_invalid_sql extends egw_exception_db { }
|
||||
|
||||
/**
|
||||
* EGroupware not (fully) installed, visit setup
|
||||
*/
|
||||
class egw_exception_db_setup extends egw_exception_db { }
|
@ -1589,7 +1589,12 @@ function egw_exception_handler(Exception $e)
|
||||
$message .= html::htmlspecialchars($e->getTraceAsString());
|
||||
}
|
||||
$message .= "</pre>\n";
|
||||
if (is_object($GLOBALS['egw']) && isset($GLOBALS['egw']->session) && method_exists($GLOBALS['egw'],'link'))
|
||||
if (is_a($e, 'egw_exception_db_setup'))
|
||||
{
|
||||
$setup_dir = str_replace(array('home/index.php','index.php'),'setup/',$_SERVER['PHP_SELF']);
|
||||
$message .= '<a href="'.$setup_dir.'">Run setup to install or configure EGroupware.</a>';
|
||||
}
|
||||
elseif (is_object($GLOBALS['egw']) && isset($GLOBALS['egw']->session) && method_exists($GLOBALS['egw'],'link'))
|
||||
{
|
||||
$message .= '<p><a href="'.$GLOBALS['egw']->link('/index.php').'">'.try_lang('Click here to resume your eGroupWare Session.').'</a></p>';
|
||||
}
|
||||
|
@ -122,8 +122,7 @@ class setup
|
||||
|
||||
if ($connect_and_setcharset)
|
||||
{
|
||||
$this->db->Halt_On_Error = 'no'; // table might not be created at that stage
|
||||
|
||||
try {
|
||||
$this->set_table_names(); // sets/checks config- and applications-table-name
|
||||
|
||||
// Set the DB's client charset if a system-charset is set
|
||||
@ -149,7 +148,10 @@ class setup
|
||||
$this->db->Link_ID->SetCharSet($this->system_charset);
|
||||
}
|
||||
}
|
||||
$this->db->Halt_On_Error = 'yes'; // setting the default again
|
||||
}
|
||||
catch (egw_exception_db $e) {
|
||||
// table might not be created at that stage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,8 +52,7 @@ class setup_detection
|
||||
function get_db_versions($setup_info=null)
|
||||
{
|
||||
$tname = Array();
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
|
||||
try { // catch DB errors
|
||||
$GLOBALS['egw_setup']->set_table_names();
|
||||
|
||||
if($GLOBALS['egw_setup']->table_exist(array($GLOBALS['egw_setup']->applications_table),true))
|
||||
@ -108,6 +107,10 @@ class setup_detection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (egw_exception_db $e) {
|
||||
// ignore db errors
|
||||
}
|
||||
// _debug_array($setup_info);
|
||||
return $setup_info;
|
||||
}
|
||||
@ -286,9 +289,7 @@ class setup_detection
|
||||
{
|
||||
$setup_info = $setup_info ? $setup_info : $GLOBALS['setup_info'];
|
||||
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
// _debug_array($setup_info);
|
||||
|
||||
try { // catch DB errors
|
||||
if (!$GLOBALS['egw_setup']->db->Link_ID)
|
||||
{
|
||||
$old = error_reporting();
|
||||
@ -296,6 +297,10 @@ class setup_detection
|
||||
$GLOBALS['egw_setup']->db->connect();
|
||||
error_reporting($old);
|
||||
}
|
||||
}
|
||||
catch(egw_exception_db $e) {
|
||||
// ignore error
|
||||
}
|
||||
$GLOBALS['egw_setup']->set_table_names();
|
||||
|
||||
if (!$GLOBALS['egw_setup']->db->Link_ID || !$GLOBALS['egw_setup']->db->Link_ID->_connectionID)
|
||||
@ -324,15 +329,13 @@ class setup_detection
|
||||
else
|
||||
{
|
||||
/* no tables, so checking if we can create them */
|
||||
try {
|
||||
$GLOBALS['egw_setup']->db->query('CREATE TABLE egw_testrights ( testfield varchar(5) NOT NULL )');
|
||||
if(!$GLOBALS['egw_setup']->db->Errno)
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->query('DROP TABLE egw_testrights');
|
||||
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (Install Applications)';
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
catch (egw_exception_db $e) {
|
||||
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Create Database)';
|
||||
return 1;
|
||||
}
|
||||
@ -346,18 +349,21 @@ class setup_detection
|
||||
*/
|
||||
function check_config()
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
if(@$GLOBALS['egw_info']['setup']['stage']['db'] != 10)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
try { // catch db errors
|
||||
$GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'config_name,config_value',array('config_app' => 'phpgwapi'),__LINE__,__FILE__);
|
||||
while($GLOBALS['egw_setup']->db->next_record())
|
||||
{
|
||||
$config[$GLOBALS['egw_setup']->db->f(0)] = $GLOBALS['egw_setup']->db->f(1);
|
||||
}
|
||||
|
||||
}
|
||||
catch (egw_exception_db $e) {
|
||||
// ignore db errors
|
||||
}
|
||||
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 2 (Needs Configuration)';
|
||||
if(!count($config))
|
||||
{
|
||||
@ -426,7 +432,6 @@ class setup_detection
|
||||
|
||||
function check_lang($check = True)
|
||||
{
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
if($check && $GLOBALS['egw_info']['setup']['stage']['db'] != 10)
|
||||
{
|
||||
return '';
|
||||
@ -435,14 +440,17 @@ class setup_detection
|
||||
{
|
||||
$GLOBALS['setup_info'] = $GLOBALS['egw_setup']->detection->get_db_versions($GLOBALS['setup_info']);
|
||||
}
|
||||
try {
|
||||
$GLOBALS['egw_setup']->db->query($q = "SELECT DISTINCT lang FROM {$GLOBALS['egw_setup']->lang_table}",__LINE__,__FILE__);
|
||||
if($GLOBALS['egw_setup']->db->num_rows() == 0)
|
||||
}
|
||||
catch (egw_exception_db $e) {
|
||||
// ignore db error
|
||||
}
|
||||
if($e || $GLOBALS['egw_setup']->db->num_rows() == 0)
|
||||
{
|
||||
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (No languages installed)';
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(@$GLOBALS['egw_setup']->db->next_record())
|
||||
{
|
||||
$GLOBALS['egw_info']['setup']['installed_langs'][$GLOBALS['egw_setup']->db->f('lang')] = $GLOBALS['egw_setup']->db->f('lang');
|
||||
@ -459,7 +467,6 @@ class setup_detection
|
||||
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (Completed)';
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that all of an app's tables exist in the db
|
||||
@ -475,13 +482,17 @@ class setup_detection
|
||||
{
|
||||
/* Make a copy, else we send some callers into an infinite loop */
|
||||
$copy = $setup_info;
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
$table_names = $GLOBALS['egw_setup']->db->table_names();
|
||||
$tables = Array();
|
||||
try {
|
||||
$table_names = $GLOBALS['egw_setup']->db->table_names();
|
||||
foreach($table_names as $key => $val)
|
||||
{
|
||||
$tables[] = $val['table_name'];
|
||||
}
|
||||
}
|
||||
catch (egw_exception_db $e) {
|
||||
// ignore db error
|
||||
}
|
||||
foreach($copy[$appname]['tables'] as $key => $val)
|
||||
{
|
||||
if($GLOBALS['DEBUG'])
|
||||
|
@ -284,9 +284,7 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
|
||||
$db_filled_block = $setup_tpl->get_var('V_db_stage_6_pre');
|
||||
$setup_tpl->set_var('tableshave',lang('If you did not receive any errors, your applications have been'));
|
||||
|
||||
// FIXME : CAPTURE THIS OUTPUT
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'report';
|
||||
|
||||
try { // catch DB errors to report them
|
||||
switch ($GLOBALS['egw_info']['setup']['currentver']['phpgwapi'])
|
||||
{
|
||||
case 'dbcreate':
|
||||
@ -366,9 +364,11 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$GLOBALS['egw_setup']->db->Halt_On_Error = 'no';
|
||||
|
||||
}
|
||||
catch (egw_exception_db $e)
|
||||
{
|
||||
echo "<pre>".$e->getMessage()."</pre>\n";
|
||||
}
|
||||
$setup_tpl->set_var('re-check_my_installation',lang('Re-Check My Installation'));
|
||||
$setup_tpl->set_var('system_charset',$GLOBALS['egw']->system_charset);
|
||||
$setup_tpl->parse('V_db_stage_6_post','B_db_stage_6_post');
|
||||
|
Loading…
Reference in New Issue
Block a user