/** * Returns a singleton instance of Database. * * @param string Database name * @return Database_Core */ public static function instance($name = 'default') { if (!isset(Database::$instances[$name])) { // Load the configuration for this database group $config = Kohana::config('database.' . $name); if (is_string($config['connection'])) { // Parse the DSN into connection array $config['connection'] = Database::parse_dsn($config['connection']); } // Set the driver class name $driver = 'Database_' . ucfirst($config['connection']['type']); // Create the database connection instance Database::$instances[$name] = new $driver($config); } return Database::$instances[$name]; }
/** * new Database('default'); * * 支持 `new Database('mysqli://*****:*****@127.0.0.1/myqee/');` 的方式 * * @param string $config_name 默认值为 `Database::DEFAULT_CONFIG_NAME` * @return void */ public function __construct($config_name = null) { if (null === $config_name) { $config_name = Database::DEFAULT_CONFIG_NAME; } if (is_array($config_name)) { $this->config = $config_name; } elseif (false !== strpos($config_name, '://')) { list($type) = explode('://', $config_name); $this->config = array('type' => $type, 'connection' => $config_name, 'table_prefix' => '', 'charset' => 'utf8', 'caching' => false, 'profiling' => true); } else { $this->config = Core::config('database.' . $config_name); } $this->config['charset'] = strtoupper($this->config['charset']); if (!isset($this->config['auto_change_charset'])) { $this->config['auto_change_charset'] = false; } if ($this->config['auto_change_charset']) { if (isset($this->config['data_charset'])) { $this->config['data_charset'] = strtoupper($this->config['data_charset']); } else { $this->config['data_charset'] = $this->config['charset']; } } $driver = $this->config['type']; if (!$driver) { $driver = 'MySQL'; } $driver = 'Database_Driver_' . $driver; if (!class_exists($driver, true)) { throw new Exception('Database Driver:' . $driver . ' not found.'); } if (!isset($this->config['connection'])) { throw new Exception('Database connection not set.'); } if (is_string($this->config['connection'])) { $this->config['connection'] = Database::parse_dsn($this->config['connection']); } # 当前驱动 $this->driver = new $driver($this->config); parent::__construct(); # 增加自动关闭连接列队 Core::add_close_connect_class('Database'); }
/** * 获取需要检测的mysql服务器列表 * * 返回的内容类似 * * array * ( * '127.0.0.1:3307' => array * ( * 'database' => 'test', * 'username' => 'root', * 'password' => '123456, * ), * '127.0.0.1:3308' => array * ( * 'database' => 'test', * 'username' => 'root', * 'password' => '123456, * ), * ) * * @return array */ protected function mysql_get_servers() { // 获取所有database的配置 $all_config = Core::config('database'); // runtime数据库相关设置 /* // 例如: $runtime_config = array ( //相关设置,比如可以设定不同的用户名和密码和库 'servers' => array ( '127.0.0.1:3306' => array('username'=>'root','password'=>'123456'), ), 'ignore' => array('127.0.0.1:3306'), //忽略的服务器 ); */ $runtime_config = Core::config('core.server_runtime.database'); $mysql_servers = array(); foreach ($all_config as $name => $config) { if ($config['connection']) { // 解析connection,比如 mysql::test:123@127.0.0.1:3360/test if (!is_array($config['connection'])) { $config['connection'] = Database::parse_dsn($config['connection']); } // 端口 $port = $config['port'] ? $config['port'] : 3306; if (is_array($config['connection']['hostname'])) { foreach ($config['connection']['hostname'] as $hostname) { if (is_array($hostname)) { foreach ($hostname as $s) { $mysql_servers[$s . ':' . $port] = array('database' => $config['database'], 'username' => $config['username'], 'password' => $config['password']); } } } } } } // 处理忽略不检查的数据库 if (isset($runtime_config['ignore']) && $runtime_config['ignore']) { if (is_array($runtime_config['ignore'])) { foreach ($runtime_config['ignore'] as $ignore_server) { if (false === strpos($ignore_server, ':')) { $ignore_server .= ':3306'; } unset($mysql_servers[$ignore_server]); } } else { if (false === strpos($runtime_config['ignore'], ':')) { $runtime_config['ignore'] .= ':3306'; } unset($mysql_servers[$runtime_config['ignore']]); } } if (isset($runtime_config['servers']) && is_array($runtime_config['servers']) && $runtime_config['servers']) { foreach ($runtime_config['servers'] as $s => $c) { if (!is_array($c)) { $this->output('runtime servers config error,key=' . $s . '. this value need an array like :' . "array('username'=>'root','password'=>'123456')"); continue; } if (false === strpos($s, ':')) { $s .= ':3306'; } if (isset($mysql_servers[$s])) { $mysql_servers[$s] = array_merge($mysql_servers[$s], $c); } } } $mysql_servers = array('127.0.0.1:3306' => array('username' => 'root', 'password' => 123456), '127.0.0.1:3309' => array('username' => 'root', 'password' => 123456)); if (!$mysql_servers) { $this->output('no server.'); } else { $this->output('server list:'); print_r($mysql_servers); } return $mysql_servers; }
/** * @dataProvider parse_dsn_provider * @test */ public function parse_dsn($dsn, $expected) { $result = Database::parse_dsn($dsn); $this->assertEquals($expected, $result); }
/** * Sets the initial columns to select from. * * @param array column list * @return void */ public function __construct($config_name = 'default') { if (is_array($config_name)) { $this->config = $config_name; } else { $this->config = Core::config('database.' . $config_name); } $this->config['charset'] = strtoupper($this->config['charset']); if (!isset($this->config['auto_change_charset'])) { $this->config['auto_change_charset'] = false; } if ($this->config['auto_change_charset']) { if (isset($this->config['data_charset'])) { $this->config['data_charset'] = strtoupper($this->config['data_charset']); } else { $this->config['data_charset'] = $this->config['charset']; } } $driver = $this->config['type']; if (!$driver) { $driver = 'MySQL'; } $driver = 'Database_Driver_' . $driver; if (!class_exists($driver, true)) { throw new Exception('Database Driver:' . $driver . ' not found.'); } if (is_string($this->config['connection'])) { $this->config['connection'] = Database::parse_dsn($this->config['connection']); } # 当前驱动 $this->driver = new $driver($this->config); parent::__construct(); # 增加自动关闭连接列队 Core::add_close_connect_class('Database'); }