Index: branches/unlabeled/unlabeled-1.9.2/core/install.php =================================================================== diff -u -N -r8212 -r8607 --- branches/unlabeled/unlabeled-1.9.2/core/install.php (.../install.php) (revision 8212) +++ branches/unlabeled/unlabeled-1.9.2/core/install.php (.../install.php) (revision 8607) @@ -228,7 +228,7 @@ case 'db_config': $section_name = 'Database'; - $fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBUserPassword', 'TablePrefix'); + $fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBUserPassword', 'DBCollation', 'TablePrefix'); if (!isset($this->systemConfig[$section_name])) { $this->systemConfig[$section_name] = Array (); @@ -316,7 +316,7 @@ case 'db_config': // 1. check if required fields are filled $section_name = 'Database'; - $required_fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser'); + $required_fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBCollation'); foreach ($required_fields as $required_field) { if (!$this->systemConfig[$section_name][$required_field]) { $status = false; @@ -363,6 +363,16 @@ switch ($this->currentStep) { case 'db_config': // store db configuration + $sql = 'SHOW COLLATION + LIKE \''.$this->systemConfig['Database']['DBCollation'].'\''; + $collation_info = $this->Conn->Query($sql); + if ($collation_info) { + $this->systemConfig['Database']['DBCharset'] = $collation_info[0]['Charset']; + + // database is already connected, that's why set collation on the fly + $this->Conn->Query('SET NAMES \''.$this->systemConfig['Database']['DBCharset'].'\' COLLATE \''.$this->systemConfig['Database']['DBCollation'].'\''); + } + $this->SaveConfig(); // import base data into database @@ -622,7 +632,6 @@ return false; } - $this->Conn = new kDBConnection($this->systemConfig['Database']['DBType'], Array(&$this, 'DBErrorHandler')); $this->Conn->Connect($this->systemConfig['Database']['DBHost'], $this->systemConfig['Database']['DBUser'], $this->systemConfig['Database']['DBUserPassword'], $this->systemConfig['Database']['DBName']); return $this->Conn->errorCode == 0; @@ -771,6 +780,12 @@ if (!$sql) { continue; // usually last line } + + if (substr($sql, 0, 13) == 'CREATE TABLE ') { + // it is CREATE TABLE statement -> add collation + $sql .= ' COLLATE \''.$this->systemConfig['Database']['DBCollation'].'\''; + } + $this->Conn->Query($sql); if ($this->Conn->getErrorCode() != 0) { $this->errorMessage = 'Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg().'

Database Query:
'.htmlspecialchars($sql).'
'; Index: branches/unlabeled/unlabeled-1.53.2/core/kernel/startup.php =================================================================== diff -u -N -r8211 -r8607 --- branches/unlabeled/unlabeled-1.53.2/core/kernel/startup.php (.../startup.php) (revision 8211) +++ branches/unlabeled/unlabeled-1.53.2/core/kernel/startup.php (.../startup.php) (revision 8607) @@ -54,6 +54,11 @@ define('SQL_USER', $vars['DBUser']); define('SQL_PASS', $vars['DBUserPassword']); define('SQL_DB', $vars['DBName']); + + if (isset($vars['DBCollation']) && isset($vars['DBCharset'])) { + define('SQL_COLLATION', $vars['DBCollation']); + define('SQL_CHARSET', $vars['DBCharset']); + } define('TABLE_PREFIX', $vars['TablePrefix']); Index: branches/unlabeled/unlabeled-1.19.2/core/kernel/db/db_connection.php =================================================================== diff -u -N -r8111 -r8607 --- branches/unlabeled/unlabeled-1.19.2/core/kernel/db/db_connection.php (.../db_connection.php) (revision 8111) +++ branches/unlabeled/unlabeled-1.19.2/core/kernel/db/db_connection.php (.../db_connection.php) (revision 8607) @@ -13,23 +13,23 @@ * @access private */ var $dbType = 'mysql'; - + /** * Created connection handle * * @var resource * @access private */ var $connectionID = null; - + /** * Handle of currenty processed recordset * * @var resource * @access private */ var $queryID = null; - + /** * DB type specific function mappings * @@ -53,7 +53,7 @@ * @access private */ var $errorCode = 0; - + /** * Error message * @@ -77,7 +77,7 @@ * @var string */ var $lastQuery = ''; - + /** * Initializes connection class with * db type to used in future @@ -157,7 +157,7 @@ /*if (!isset($this->metaFunctions[$name])) { $this->metaFunctions[$name] = $name; }*/ - + return $this->dbType.'_'.$name; } @@ -181,6 +181,11 @@ if (defined('DBG_SQL_MODE')) { $this->Query('SET sql_mode = \''.DBG_SQL_MODE.'\''); } + + if (defined('SQL_COLLATION') && defined('SQL_CHARSET')) { + $this->Query('SET NAMES \''.SQL_CHARSET.'\' COLLATE \''.SQL_COLLATION.'\''); + } + $this->setDB($db); $this->showError(); } @@ -402,7 +407,9 @@ } // set 2nd checkpoint: begin if(!$isSkipTable) { - $debugger->profileFinish('sql_'.$queryID); + $first_cell = count($ret) == 1 && count(current($ret)) == 1 ? current(current($ret)) : null; + + $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows(), $first_cell); $debugger->profilerAddTotal('sql', 'sql_'.$queryID); } $this->Destroy(); @@ -412,7 +419,7 @@ else { // set 2nd checkpoint: begin if(!$isSkipTable) { - $debugger->profileFinish('sql_'.$queryID); + $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows()); $debugger->profilerAddTotal('sql', 'sql_'.$queryID); } // set 2nd checkpoint: end @@ -572,7 +579,7 @@ return $this->ChangeQuery($sql); } - + /** * Allows to detect table's presense in database * @@ -582,15 +589,15 @@ function TableFound($table_name) { static $table_found = Array(); - + if (!preg_match('/^'.preg_quote(TABLE_PREFIX, '/').'(.*)/', $table_name)) { $table_name = TABLE_PREFIX.$table_name; } - + if (!isset($table_found[$table_name])) { $table_found[$table_name] = $this->Query('SHOW TABLES LIKE "'.$table_name.'"'); } - + return $table_found[$table_name]; } } Index: branches/unlabeled/unlabeled-1.178.2/core/kernel/application.php =================================================================== diff -u -N -r8274 -r8607 --- branches/unlabeled/unlabeled-1.178.2/core/kernel/application.php (.../application.php) (revision 8274) +++ branches/unlabeled/unlabeled-1.178.2/core/kernel/application.php (.../application.php) (revision 8607) @@ -225,8 +225,8 @@ } $this->Conn = new kDBConnection(SQL_TYPE, Array(&$this, 'handleSQLError') ); - $this->Conn->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); $this->Conn->debugMode = $this->isDebugMode(); + $this->Conn->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); $this->Factory = new kFactory(); $this->registerDefaultClasses(); Index: branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/db_config.tpl =================================================================== diff -u -N -r8254 -r8607 --- branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/db_config.tpl (.../db_config.tpl) (revision 8254) +++ branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/db_config.tpl (.../db_config.tpl) (revision 8607) @@ -1,11 +1,11 @@ Server Type*: - + - + Database Name*: - + - Database User Name*: - - - - - + Database Collation*: + + + + + - Database User Password: - - - + Database User Name*: + + + - + - Table Name Prefix: - - - + Database User Password: + + + + + + + Table Name Prefix: + + + \ No newline at end of file Index: branches/unlabeled/unlabeled-1.69.2/core/kernel/utility/debugger.php =================================================================== diff -u -N -r8173 -r8607 --- branches/unlabeled/unlabeled-1.69.2/core/kernel/utility/debugger.php (.../debugger.php) (revision 8173) +++ branches/unlabeled/unlabeled-1.69.2/core/kernel/utility/debugger.php (.../debugger.php) (revision 8607) @@ -104,7 +104,7 @@ * * @param string $ip_list semi-column (by default) separated ip address list * @param string $separator ip address separator (default ";") - * + * * @return bool */ function ipMatch($ip_list, $separator = ';') @@ -117,10 +117,10 @@ break; } } - + return $ip_match; } - + /** * Set's default values to constants debugger uses * @@ -265,16 +265,16 @@ { $dump_mode = 'var_dump'; $dumpVars = func_get_args(); - + if ($dumpVars[count($dumpVars) - 1] === 'STRICT') { $dump_mode = 'strict_var_dump'; array_pop($dumpVars); } - + foreach ($dumpVars as $varValue) { $this->Data[] = Array('value' => $varValue, 'debug_type' => $dump_mode); } - + } function prepareHTML($dataIndex) @@ -299,7 +299,7 @@ case 'strict_var_dump': return $this->highlightString( var_export($Data['value'], true) ); break; - + case 'trace': ini_set('memory_limit', '500M'); $trace =& $Data['trace']; @@ -325,7 +325,7 @@ if ($has_args) { // if parameter value is longer then 200 symbols, then leave only first 50 - $args = $this->highlightString($this->print_r($traceRec['args'], true, 50, 200)); + $args = $this->highlightString($this->print_r($traceRec['args'], true)); $ret .= ''; } $i++; @@ -344,19 +344,29 @@ $total = $this->ProfilerTotals[$totals_key]; $div_width = Array(); - $total_width = ($this->getWindowWidth()-10); + $total_width = ($this->getWindowWidth() - 10); $div_width['before'] = round(($total_before / $total) * $total_width); $div_width['current'] = round(($runtime / $total) * $total_width); $div_width['left'] = round((($total - $total_before - $runtime) / $total) * $total_width); $ret = 'Name: '.$Data['description'].'
'; + $additional = isset($Data['additional']) ? $Data['additional'] : Array (); if (isset($Data['file'])) { + array_unshift($additional, Array('name' => 'File', 'value' => $this->getFileLink($Data['file'], $Data['line'], basename($Data['file']).':'.$Data['line']))); + } + array_unshift($additional, Array('name' => 'Runtime', 'value' => $runtime.'s')); + + foreach ($additional as $mixed_param) { + $ret .= '['.$mixed_param['name'].': '.$mixed_param['value'].'] '; + } + + /*if (isset($Data['file'])) { $ret .= '[Runtime: '.$runtime.'s] [File: '.$this->getFileLink($Data['file'], $Data['line'], basename($Data['file']).':'.$Data['line']).']
'; } else { - $ret .= 'Runtime: '.$runtime.'s
'; - } + $ret .= 'Runtime: '.$runtime.'s
'; + }*/ $ret .= '
'; $ret .= '
'; @@ -409,22 +419,32 @@ * * @param Array $array * @param bool $return_output return output or print it out - * @param int $cut_first cut first N symbols, don't cut anything if -1 specified - * @package int $cut_min_length cut only of this length of string or greather + * @param int $tab_count offset in tabs * @return string */ - function print_r(&$array, $return_output = false, $cut_first = -1, $cut_min_length = -1) + function print_r(&$array, $return_output = false, $tab_count = -1) { - static $first_line = true, $tab_count = -1; + static $first_line = true; - if (is_null($array)) { - return 'NULL'; - } - elseif (!is_array($array)) { - if ($cut_min_length != -1 && strlen($array) > $cut_min_length) { - $array = substr($array, 0, $cut_first).' ...'; + // not an array at all + if (!is_array($array)) { + switch (gettype($array)) { + case 'NULL': + return 'NULL'."\n"; + break; + + case 'object': + return $this->processObject($array, $tab_count); + break; + + default: + // number or string + if (strlen($array) > 200) { + $array = substr($array, 0, 50).' ...'; + } + return $array."\n"; + break; } - return $array; } $output = ''; @@ -440,7 +460,7 @@ foreach ($array_keys as $key) { switch (gettype($array[$key])) { case 'array': - $output .= $tabsign.'['.$key.'] = '.$this->print_r($array[$key], true, 50, 200); + $output .= $tabsign.'['.$key.'] = '.$this->print_r($array[$key], true, $tab_count); break; case 'boolean': @@ -450,8 +470,8 @@ case 'integer': case 'double': case 'string': - if ($cut_min_length != -1 && strlen($array[$key]) > $cut_min_length) { - $array[$key] = substr($array[$key], 0, $cut_first).' ...'; + if (strlen($array[$key]) > 200) { + $array[$key] = substr($array[$key], 0, 50).' ...'; } $output .= $tabsign.'['.$key.'] = '.$array[$key]."\n"; break; @@ -461,42 +481,10 @@ break; case 'object': - $attribute_names = get_class_vars( get_class($array[$key]) ); - if (!$attribute_names) { - $output .= $tabsign.'['.$key."] = NO_ATTRIBUTES\n"; - } - else { - if ($this->IsBigObject($array[$key])) { - $output .= $tabsign.'['.$key.'] = SKIPPED (class: '.get_class($array[$key]).")\n"; - break; - } - - // $attribute_value - default value for this attribute, not used here - foreach ($attribute_names as $attribute_name => $attribute_value) { - if (is_object($array[$key]->$attribute_name)) { - // it is object - $object_class = get_class($array[$key]->$attribute_name); - if (!in_array($object_class, $this->RecursionStack)) { - // object [not in recursion stack] - if ($this->IsBigObject($array[$key]->$attribute_name)) { - $output .= $tabsign.'['.$attribute_name.'] = SKIPPED (class: '.$object_class.")\n"; - continue; - } - - array_push($this->RecursionStack, $object_class); - $output .= $this->print_r($array[$key]->$attribute_name, true, 50, 200); - array_pop($this->RecursionStack); - } - else { - // object [in recursion stack] - $output .= $tabsign.'['.$attribute_name.'] = *** RECURSION *** (class: '.$object_class.")\n"; - } - } - else { - $output .= $tabsign.'['.$attribute_name.'] = '.$this->print_r($array[$key]->$attribute_name, true, 50, 200)."\n"; - } - } - } + $output .= $tabsign.'['.$key."] = "; + $output .= "Object (".get_class($array[$key]).") = \n".str_repeat(' ', $tab_count + 1)."(\n"; + $output .= $this->processObject($array[$key], $tab_count + 2); + $output .= str_repeat(' ', $tab_count + 1).")\n"; break; default: @@ -525,18 +513,40 @@ return true; } - /** - * Returns only first 200 chars of string, this allow to save amount of data sent to browser - * - * @param string $string - * @return string - */ - function cutStringForHTML($string) + function processObject(&$object, $tab_count) { - if (strlen($string) > 200) { - $string = substr($string,0,50).' ...'; + $object_class = get_class($object); + if (!in_array($object_class, $this->RecursionStack)) { + if ($this->IsBigObject($object)) { + return 'SKIPPED (class: '.$object_class.")\n"; + } + + $attribute_names = get_class_vars($object_class); + if (!$attribute_names) { + return "NO_ATTRIBUTES\n"; + } + else { + $output = ''; + array_push($this->RecursionStack, $object_class); + + $tabsign = $tab_count ? str_repeat(' ', $tab_count) : ''; + foreach ($attribute_names as $attribute_name => $attribute_value) { + if (is_object($object->$attribute_name)) { + // it is object + $output .= $tabsign.'['.$attribute_name.'] = '.$this->processObject($object->$attribute_name, $tab_count + 1); + } + else { + $output .= $tabsign.'['.$attribute_name.'] = '.$this->print_r($object->$attribute_name, true, $tab_count); + } + } + array_pop($this->RecursionStack); + return $output; + } } - return $string; + else { + // object [in recursion stack] + return '*** RECURSION *** (class: '.$object_class.")\n"; + } } /** @@ -783,6 +793,22 @@ if (isset($description)) { $this->ProfilerData[$key]['description'] = $description; } + + if (substr($key, 0, 4) == 'sql_') { + $func_arguments = func_get_args(); + $rows_affected = $func_arguments[3]; + + if ($rows_affected > 0) { + $additional = Array ( + Array ('name' => 'Affected Rows', 'value' => $rows_affected), + ); + + if (isset($func_arguments[4])) { + $additional[] = Array ('name' => 'Result', 'value' => $func_arguments[4]); + } + $this->ProfilerData[$key]['additional'] =& $additional; + } + } } function profilerAddTotal($total_key, $key = null, $value = null) @@ -843,7 +869,7 @@ if (defined('E_RECOVERABLE_ERROR')) { $error_map['Fatal Error (recoverable)'] = Array(E_RECOVERABLE_ERROR); } - + foreach ($error_map as $error_name => $error_codes) { if (in_array($error_code, $error_codes)) { return $error_name; @@ -1046,12 +1072,14 @@ // we have sql & error count in toolbar, don't duplicate here $info = Array( 'Script Runtime' => 'PROFILE:script_runtime', + 'SQL\'s Runtime' => 'PROFILE_T:sql', ); } else { // toolbar not visible, then show sql & error count too $info = Array ( 'Script Runtime' => 'PROFILE:script_runtime', + 'SQL\'s Runtime' => 'PROFILE_T:sql', '-' => 'SEP:-', 'Notice / Warning' => 'PROFILE_TC:error_handling', 'SQLs Count' => 'PROFILE_TC:sql', @@ -1076,6 +1104,11 @@ $ret .= ''.$record_cell.$title.':'.$record_cell.''.$this->ProfilerTotalCount[$record_data].''; break; + case 'PROFILE_T': // profile total + $record_cell = ''; + $ret .= ''.$record_cell.$title.':'.$record_cell.''.sprintf('%.5f', $this->ProfilerTotals[$record_data]).' s'; + break; + case 'SEP': $ret .= ''; break;