<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Code Igniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* Database Utility Class
* 数据库实用工具类
*
* @category Database
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/database/
*/
class CI_DB_utility extends CI_DB_forge {
var $db;
//$db数据库操作对象
var $data_cache = array();
//$data_cache 数据库缓存对象
/**
* Constructor
*
* Grabs the CI super object instance so we can access it.
* 抓住CI超级对象实例,这样我们就可以访问它。
*/
function __construct()
{
// Assign the main database object to $this->db
// 主数据库对象分配到$> DB
$CI =& get_instance();
$this->db =& $CI->db;
log_message('debug', "Database Utility Class Initialized 初始化数据库实用工具类");
}
// --------------------------------------------------------------------
/**
* List databases
* 清单数据库
* @access public
* @return bool
*/
function list_databases()
{
// Is there a cached result?
// 是否有一个缓存的结果吗?
// 如果存在一个缓存值,直接返回
if (isset($this->data_cache['db_names']))
{
return $this->data_cache['db_names'];
}
//这里所执行的$this->_list_databases(); 让我有点弄不懂样,是所有数据库列表,主从数据库?
$query = $this->db->query($this->_list_databases());
$dbs = array();
if ($query->num_rows() > 0)
{
foreach ($query->result_array() as $row)
{
$dbs[] = current($row);
}
}
//将所有查询结果存放到$this->data_cache['db_names]中去
$this->data_cache['db_names'] = $dbs;
return $this->data_cache['db_names']; //然后返回缓存内容
}
// --------------------------------------------------------------------
/**
* Determine if a particular database exists
* 确定一个特定的数据库是否存在
* @access public
* @param string
* @return boolean
*/
function database_exists($database_name)
{
// Some databases won't have access to the list_databases() function, so
// this is intended to allow them to override with their own functions as
// defined in $driver_utility.php
// 有些数据库没有访问list_databases()函数,所以
// 这是为了让他们用自己的功能覆盖
// 定义$ driver_utility.php中
//在当前对象中是否有方法名 _database_exists方法
if (method_exists($this, '_database_exists'))
{
//然后从该方法中返回$database_name的值
return $this->_database_exists($database_name);
}
else
{
//判断在$this->list_databases()数组中是否存在$database_name
return ( ! in_array($database_name, $this->list_databases())) ? FALSE : TRUE;
}
}
// --------------------------------------------------------------------
/**
* Optimize Table
* 优化表
*
* @access public
* @param string the table name
* @return bool
*/
function optimize_table($table_name)
{
//操,都没有找到_optimize_table()这个函数在什么地方,继承的父类也不存在
$sql = $this->_optimize_table($table_name);
if (is_bool($sql))
{
show_error('db_must_use_set数据库必须设置为使用');
}
$query = $this->db->query($sql);
$res = $query->result_array();
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
// 注意:由于电流中的错误()影响某些版本的
// PHP,我们可以不通过函数调用直接进入
return current($res); //返回回$res当前使用的元素值返回
}
// --------------------------------------------------------------------
/**
* Optimize Database
* 优化数据库
* @access public
* @return array
*/
function optimize_database()
{
$result = array();
//循环优化数据库中的每一张数据表
foreach ($this->db->list_tables() as $table_name)
{
$sql = $this->_optimize_table($table_name);
if (is_bool($sql)) //如果$sql为bool类型
{
return $sql;
}
$query = $this->db->query($sql);
// Build the result array...
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
// 生成的结果阵列...
// 注意:由于电流中的错误()影响某些版本的
// PHP,我们可以不通过函数调用直接进入
$res = $query->result_array();
$res = current($res); //取得$res数组中前使用的值
//然后将$this->db->database."."替换为空值,在$res中
//还得从$res中取得的当前元素,这是两次了哦
$key = str_replace($this->db->database.'.', '', current($res));
//取得所有$res的keys值数组放入$keys中
$keys = array_keys($res);
unset($res[$keys[0]]); //删除$res中第一个键值
$result[$key] = $res; //放入到$result数组中,将$res
}
return $result;
}
// --------------------------------------------------------------------
/**
* Repair Table
* 维修表
* @access public
* @param string the table name
* @return bool
*/
function repair_table($table_name)
{
//_repair_table()函数在那里也没有找到
$sql = $this->_repair_table($table_name);
if (is_bool($sql))
{
return $sql;
}
$query = $this->db->query($sql);
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
// 注意:由于电流中的错误()影响某些版本的
// PHP,我们可以不通过函数调用直接进入
$res = $query->result_array();
return current($res);
}
// --------------------------------------------------------------------
/**
* Generate CSV from a query result object
* 从查询结果对象,生成CSV
* @access public
* @param object The query result object 查询结果对象
* @param string The delimiter - comma by default 默认情况下,分隔符 - 逗号
* @param string The newline character - \n by default 换行符 - \ N默认情况下,
* @param string The enclosure - double quote by default 外壳 - 默认情况下,双引号
* @return string
*/
function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
{
//$query不为对象或者在$query中找不到list_fields方法时
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
show_error('You must submit a valid result object 你必须提交一个有效的结果对象');
}
$out = '';
// First generate the headings from the table column names
// 首先生成从表中列名的标题
foreach ($query->list_fields() as $name)
{
$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
}
$out = rtrim($out);
$out .= $newline; //开始新的一行
// Next blast through the result array and build out the rows
// 下一步高炉通过阵列,打造出的行
foreach ($query->result_array() as $row)
{
foreach ($row as $item)
{
$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
}
$out = rtrim($out);
$out .= $newline;
}
return $out;
}
// --------------------------------------------------------------------
/**
* Generate XML data from a query result object
* 从查询结果对象生成XML数据
* @access public
* @param object The query result object 查询结果对象
* @param array Any preferences 任何喜好
* @return string
*/
function xml_from_result($query, $params = array())
{
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
show_error('You must submit a valid result object 你必须提交一个有效的结果对象');
}
// Set our default values
foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
{
if ( ! isset($params[$key]))
{
$params[$key] = $val;
}
}
// Create variables for convenience
//创建变量为方便起见,
//extract($params); ? 这是什么意思,也找不到extract()这个函数
extract($params);
//extract() 函数从数组中把变量导入到当前的符号表中
//对于数组中的每个元素,键名用于变量名,键值用于变量值
//第二个参数type用于指定当某个变量已经存在,而数组中又有同名元素时,extract()函数如何对待这样的冲突
// Load the xml helper
$CI =& get_instance();
$CI->load->helper('xml'); //加载xml类
// Generate the result
$xml = "<{$root}>".$newline;
foreach ($query->result_array() as $row)
{
$xml .= $tab."<{$element}>".$newline;
foreach ($row as $key => $val)
{
$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
}
$xml .= $tab."</{$element}>".$newline;
}
$xml .= "</$root>".$newline;
return $xml;
}
// --------------------------------------------------------------------
/**
* Database Backup
* 数据库备份
* @access public
* @return void
*/
function backup($params = array())
{
// If the parameters have not been submitted as an
// array then we know that it is simply the table
// name, which is a valid short cut.
// 如果参数有没有被作为一个提交
// 数组,那么我们知道,这是简单的表名称,这是一个有效的捷径。
//如果为字符串,那么放到tables中去
if (is_string($params))
{
$params = array('tables' => $params);
}
// ------------------------------------------------------
// Set up our default preferences
// 设置默认首选项
$prefs = array(
'tables' => array(),
'ignore' => array(),
'filename' => '',
'format' => 'gzip', // gzip, zip, txt
'add_drop' => TRUE,
'add_insert' => TRUE,
'newline' => "\n"
);
// Did the user submit any preferences? If so set them....
// 用户提交什么喜好?如果是这样设置....
if (count($params) > 0)
{
foreach ($prefs as $key => $val)
{
if (isset($params[$key]))
{
$prefs[$key] = $params[$key];
}
}
}
// ------------------------------------------------------
// Are we backing up a complete database or individual tables?
// If no table names were submitted we'll fetch the entire table list
// 我们是一个完整的备份数据库或单个表?
// 如果没有表名提交,我们会读取整个表列表
if (count($prefs['tables']) == 0)
{
$prefs['tables'] = $this->db->list_tables(); //备份所有表
}
// ------------------------------------------------------
// Validate the format 验证格式
if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
{
$prefs['format'] = 'txt';
}
// ------------------------------------------------------
// Is the encoder supported? If not, we'll either issue an
// error or use plain text depending on the debug settings
//编码器支持?如果没有,我们会发出
//错误,或使用纯文本,根据调试设置
if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
{
if ($this->db->db_debug)
{
return $this->db->display_error('db_unsuported_compression');
}
$prefs['format'] = 'txt';
}
// ------------------------------------------------------
// Set the filename if not provided - Only needed with Zip files
// 如果没有提供设置文件名 - 只需要与Zip文件
if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
{
$prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
$prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
}
// ------------------------------------------------------
// Was a Gzip file requested? 是一个gzip文件要求?
if ($prefs['format'] == 'gzip')
{
return gzencode($this->_backup($prefs)); //_backup在那里哈
}
// ------------------------------------------------------
// Was a text file requested?
// 是一个文本文件要求?
if ($prefs['format'] == 'txt')
{
return $this->_backup($prefs);
}
// ------------------------------------------------------
// Was a Zip file requested? Zip文件要求?
if ($prefs['format'] == 'zip')
{
// If they included the .zip file extension we'll remove it
// 如果他们包括我们会删除它。zip文件扩展名
if (preg_match("|.+?\.zip$|", $prefs['filename']))
{
$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
}
// Tack on the ".sql" file extension if needed 如果需要,在“SQL”文件扩展名德
if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
{
$prefs['filename'] .= '.sql';
}
// Load the Zip class and output it
// 加载邮编类,并输出
$CI =& get_instance();
$CI->load->library('zip'); //加载zip
//将内容添加到zip中去
$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
//返顺压缩成功以后的文件,倒低是什么什么样的文件,是二进制内容还是文件的url呢?
return $CI->zip->get_zip();
}
}
}
/* End of file DB_utility.php */
/* Location: ./system/database/DB_utility.php */