From 72f272b693cb1f8ed9b586fcaa3f43e644d90650 Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Tue, 23 Dec 2008 14:14:23 -0500 Subject: [PATCH] add a function for setting a mysql connection's charset, turning a charset name into one that mysql understands, and make sure that the charset is set on connection --- framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php | 32 ++++++++++++++++++++-- framework/Db/lib/Horde/Db/Adapter/Mysqli.php | 8 +++++- framework/Db/lib/Horde/Db/Adapter/Pdo/Mysql.php | 6 +++- framework/Db/test/Horde/Db/Adapter/MysqliTest.php | 9 +++++- .../Db/test/Horde/Db/Adapter/Pdo/MysqlTest.php | 9 +++++- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php b/framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php index 023660093..92a300adf 100644 --- a/framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php +++ b/framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php @@ -134,13 +134,41 @@ class Horde_Db_Adapter_Mysql_Schema extends Horde_Db_Adapter_Abstract_Schema } /** - * Returns the database character set + * Returns the database character set that query results are in * * @return string */ public function getCharset() { - return $this->showVariable('character_set_database'); + return $this->showVariable('character_set_results'); + } + + /** + * Set the client and result charset. + * + * @param string $charset The character set to use for client queries and results. + */ + public function setCharset($charset) + { + $charset = $this->_mysqlCharsetName($charset); + $this->execute('SET NAMES ' . $this->quoteString($charset)); + } + + /** + * Get the MySQL name of a given character set. + * + * @param string $charset + * @return string MySQL-normalized charset. + */ + public function _mysqlCharsetName($charset) + { + $charset = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $charset)); + $validCharsets = $this->selectValues('SHOW CHARACTER SET'); + if (!in_array($charset, $validCharsets)) { + throw new Horde_Db_Exception($charset . ' is not supported by MySQL'); + } + + return $charset; } /** diff --git a/framework/Db/lib/Horde/Db/Adapter/Mysqli.php b/framework/Db/lib/Horde/Db/Adapter/Mysqli.php index 662b6bcaf..e7798996b 100644 --- a/framework/Db/lib/Horde/Db/Adapter/Mysqli.php +++ b/framework/Db/lib/Horde/Db/Adapter/Mysqli.php @@ -134,11 +134,17 @@ class Horde_Db_Adapter_Mysqli extends Horde_Db_Adapter_Abstract // If supported, request real datatypes from MySQL instead of returning // everything as a string. - if (defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) + if (defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) { $mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); + } $this->_connection = $mysqli; $this->_active = true; + + // Set the default charset. http://dev.mysql.com/doc/refman/5.1/en/charset-connection.html + if (!empty($config['charset'])) { + $this->setCharset($config['charset']); + } } /** diff --git a/framework/Db/lib/Horde/Db/Adapter/Pdo/Mysql.php b/framework/Db/lib/Horde/Db/Adapter/Pdo/Mysql.php index ff2b6eed5..c9d59405c 100644 --- a/framework/Db/lib/Horde/Db/Adapter/Pdo/Mysql.php +++ b/framework/Db/lib/Horde/Db/Adapter/Pdo/Mysql.php @@ -59,7 +59,11 @@ class Horde_Db_Adapter_Pdo_Mysql extends Horde_Db_Adapter_Pdo_Abstract parent::connect(); // ? $this->_connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); - // SET NAMES ? + + // Set the default charset. http://dev.mysql.com/doc/refman/5.1/en/charset-connection.html + if (!empty($this->_config['charset'])) { + $this->setCharset($this->_config['charset']); + } } diff --git a/framework/Db/test/Horde/Db/Adapter/MysqliTest.php b/framework/Db/test/Horde/Db/Adapter/MysqliTest.php index 7eed22dd6..c058adf33 100644 --- a/framework/Db/test/Horde/Db/Adapter/MysqliTest.php +++ b/framework/Db/test/Horde/Db/Adapter/MysqliTest.php @@ -128,6 +128,11 @@ class Horde_Db_Adapter_MysqliTest extends PHPUnit_Framework_TestCase $this->assertTrue($this->_conn->supportsCountDistinct()); } + public function testGetCharset() + { + $this->assertEquals('utf8', strtolower($this->_conn->getCharset())); + } + /*########################################################################## # Database Statements @@ -653,6 +658,8 @@ class Horde_Db_Adapter_MysqliTest extends PHPUnit_Framework_TestCase public function testStructureDump() { $this->_createTestTable('sports'); + // Avoid AUTO_INCREMENT being a part of the dump + $this->_conn->execute('TRUNCATE TABLE sports'); // single table $structure = $this->_conn->structureDump('sports'); @@ -662,7 +669,7 @@ class Horde_Db_Adapter_MysqliTest extends PHPUnit_Framework_TestCase " `name` varchar(255) DEFAULT NULL,\n". " `is_college` tinyint(1) DEFAULT NULL,\n". " PRIMARY KEY (`id`)\n". - ") ENGINE=InnoDB"; + ") ENGINE=InnoDB DEFAULT CHARSET=utf8"; // MySQL differs in how it dumps table structure between versions, so do // some normalization. diff --git a/framework/Db/test/Horde/Db/Adapter/Pdo/MysqlTest.php b/framework/Db/test/Horde/Db/Adapter/Pdo/MysqlTest.php index c1a14f74a..2ee5de605 100644 --- a/framework/Db/test/Horde/Db/Adapter/Pdo/MysqlTest.php +++ b/framework/Db/test/Horde/Db/Adapter/Pdo/MysqlTest.php @@ -128,6 +128,11 @@ class Horde_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase $this->assertTrue($this->_conn->supportsCountDistinct()); } + public function testGetCharset() + { + $this->assertEquals('utf8', strtolower($this->_conn->getCharset())); + } + /*########################################################################## # Database Statements @@ -653,6 +658,8 @@ class Horde_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase public function testStructureDump() { $this->_createTestTable('sports'); + // Avoid AUTO_INCREMENT being a part of the dump + $this->_conn->execute('TRUNCATE TABLE sports'); // single table $structure = $this->_conn->structureDump('sports'); @@ -662,7 +669,7 @@ class Horde_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase " `name` varchar(255) DEFAULT NULL,\n". " `is_college` tinyint(1) DEFAULT NULL,\n". " PRIMARY KEY (`id`)\n". - ") ENGINE=InnoDB"; + ") ENGINE=InnoDB DEFAULT CHARSET=utf8"; // MySQL differs in how it dumps table structure between versions, so do // some normalization. -- 2.11.0