From e85fe0cffcf6ace5288f47497b3054a0a5a08594 Mon Sep 17 00:00:00 2001 From: Thomas Jakobi Date: Mon, 8 Mar 2021 18:54:28 +0100 Subject: [PATCH 1/5] Set the charset of the table/column on base of the connection charset Fix #175 --- xpdo/om/mysql/xpdomanager.class.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/xpdo/om/mysql/xpdomanager.class.php b/xpdo/om/mysql/xpdomanager.class.php index 711202ec..38efd8af 100644 --- a/xpdo/om/mysql/xpdomanager.class.php +++ b/xpdo/om/mysql/xpdomanager.class.php @@ -124,7 +124,9 @@ public function removeObjectContainer($className) { public function createObjectContainer($className) { $created= false; - if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { + $connection = $this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true)); + if ($connection) { + $charset = $connection->getOption('charset'); $instance= $this->xpdo->newObject($className); if ($instance) { $tableName= $this->xpdo->getTableName($className); @@ -144,7 +146,7 @@ public function createObjectContainer($className) { $fieldMeta = $this->xpdo->getFieldMeta($className, true); $columns = array(); foreach ($fieldMeta as $key => $meta) { - $columns[] = $this->getColumnDef($className, $key, $meta); + $columns[] = $this->getColumnDef($className, $key, $meta, array('charset' => $charset)); /* Legacy index support for pre-2.0.0-rc3 models */ if ($legacyIndexes && isset ($meta['index']) && $meta['index'] !== 'pk') { if ($meta['index'] === 'fulltext') { @@ -250,6 +252,9 @@ public function createObjectContainer($className) { $sql .= ")"; if (!empty($tableType)) { $sql .= " ENGINE={$tableType}"; + if (!empty($charset)) { + $sql .= " DEFAULT CHARSET={$charset}"; + } } $created= $this->xpdo->exec($sql); if ($created === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) { @@ -436,6 +441,10 @@ protected function getColumnDef($class, $name, $meta, array $options = array()) if (empty ($extra) && isset ($meta['extra'])) { $extra= ' ' . $meta['extra']; } + $charset = ''; + if (isset ($options['charset']) && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { + $charset = ' CHARACTER SET ' . $options['charset']; + } $default= ''; if (isset ($meta['default']) && !preg_match($lobsPattern, $dbtype)) { $defaultVal= $meta['default']; @@ -447,9 +456,9 @@ protected function getColumnDef($class, $name, $meta, array $options = array()) } $attributes= (isset ($meta['attributes'])) ? ' ' . $meta['attributes'] : ''; if (strpos(strtolower($attributes), 'unsigned') !== false) { - $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $attributes . $null . $default . $extra; + $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $attributes . $charset . $null . $default . $extra; } else { - $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $null . $default . $attributes . $extra; + $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $charset . $null . $default . $attributes . $extra; } return $result; } From b0f7b10a1ffea4344b2a2c1fe04021e4cd88f018 Mon Sep 17 00:00:00 2001 From: Thomas Jakobi Date: Mon, 8 Mar 2021 19:02:04 +0100 Subject: [PATCH 2/5] Set the charset even if tableType is empty --- xpdo/om/mysql/xpdomanager.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xpdo/om/mysql/xpdomanager.class.php b/xpdo/om/mysql/xpdomanager.class.php index 38efd8af..5c4a0f1e 100644 --- a/xpdo/om/mysql/xpdomanager.class.php +++ b/xpdo/om/mysql/xpdomanager.class.php @@ -252,9 +252,9 @@ public function createObjectContainer($className) { $sql .= ")"; if (!empty($tableType)) { $sql .= " ENGINE={$tableType}"; - if (!empty($charset)) { - $sql .= " DEFAULT CHARSET={$charset}"; - } + } + if (!empty($charset)) { + $sql .= " DEFAULT CHARSET={$charset}"; } $created= $this->xpdo->exec($sql); if ($created === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) { From 2923bb8566ab9dfc7366da04fa4fe472d76fc809 Mon Sep 17 00:00:00 2001 From: Thomas Jakobi Date: Wed, 7 Apr 2021 11:58:51 +0200 Subject: [PATCH 3/5] Set the collation of the table/column on base of the connection collation --- xpdo/om/mysql/xpdomanager.class.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/xpdo/om/mysql/xpdomanager.class.php b/xpdo/om/mysql/xpdomanager.class.php index 5c4a0f1e..544f8181 100644 --- a/xpdo/om/mysql/xpdomanager.class.php +++ b/xpdo/om/mysql/xpdomanager.class.php @@ -127,6 +127,7 @@ public function createObjectContainer($className) { $connection = $this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true)); if ($connection) { $charset = $connection->getOption('charset'); + $collation = $connection->getOption('collation'); $instance= $this->xpdo->newObject($className); if ($instance) { $tableName= $this->xpdo->getTableName($className); @@ -146,7 +147,7 @@ public function createObjectContainer($className) { $fieldMeta = $this->xpdo->getFieldMeta($className, true); $columns = array(); foreach ($fieldMeta as $key => $meta) { - $columns[] = $this->getColumnDef($className, $key, $meta, array('charset' => $charset)); + $columns[] = $this->getColumnDef($className, $key, $meta, array('charset' => $charset, 'collation' => $collation)); /* Legacy index support for pre-2.0.0-rc3 models */ if ($legacyIndexes && isset ($meta['index']) && $meta['index'] !== 'pk') { if ($meta['index'] === 'fulltext') { @@ -252,9 +253,12 @@ public function createObjectContainer($className) { $sql .= ")"; if (!empty($tableType)) { $sql .= " ENGINE={$tableType}"; - } - if (!empty($charset)) { - $sql .= " DEFAULT CHARSET={$charset}"; + if (!empty($charset)) { + $sql .= " DEFAULT CHARSET={$charset}"; + if (!empty($collation)) { + $sql .= " COLLATE={$collation}"; + } + } } $created= $this->xpdo->exec($sql); if ($created === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) { @@ -442,8 +446,11 @@ protected function getColumnDef($class, $name, $meta, array $options = array()) $extra= ' ' . $meta['extra']; } $charset = ''; - if (isset ($options['charset']) && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { + if (isset($options['charset']) && $options['charset'] != '' && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { $charset = ' CHARACTER SET ' . $options['charset']; + if (isset($options['collation']) && $options['collation'] != '') { + $charset .= ' COLLATE ' . $options['collation']; + } } $default= ''; if (isset ($meta['default']) && !preg_match($lobsPattern, $dbtype)) { From 8ca5a7b1e113547ffb7469cea2a8fd2f6d547200 Mon Sep 17 00:00:00 2001 From: Thomas Jakobi Date: Wed, 7 Apr 2021 12:05:34 +0200 Subject: [PATCH 4/5] Change the check to not empty --- xpdo/om/mysql/xpdomanager.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xpdo/om/mysql/xpdomanager.class.php b/xpdo/om/mysql/xpdomanager.class.php index 544f8181..c1994ff1 100644 --- a/xpdo/om/mysql/xpdomanager.class.php +++ b/xpdo/om/mysql/xpdomanager.class.php @@ -446,9 +446,9 @@ protected function getColumnDef($class, $name, $meta, array $options = array()) $extra= ' ' . $meta['extra']; } $charset = ''; - if (isset($options['charset']) && $options['charset'] != '' && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { + if (!empty($options['charset']) && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { $charset = ' CHARACTER SET ' . $options['charset']; - if (isset($options['collation']) && $options['collation'] != '') { + if (!empty($options['charset'])) { $charset .= ' COLLATE ' . $options['collation']; } } From 49b85bd971c96137d6f8c3e99ab29ce650452524 Mon Sep 17 00:00:00 2001 From: Thomas Jakobi Date: Fri, 9 Apr 2021 22:28:13 +0200 Subject: [PATCH 5/5] Fix a wrong key usage --- xpdo/om/mysql/xpdomanager.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xpdo/om/mysql/xpdomanager.class.php b/xpdo/om/mysql/xpdomanager.class.php index c1994ff1..87355d56 100644 --- a/xpdo/om/mysql/xpdomanager.class.php +++ b/xpdo/om/mysql/xpdomanager.class.php @@ -448,7 +448,7 @@ protected function getColumnDef($class, $name, $meta, array $options = array()) $charset = ''; if (!empty($options['charset']) && in_array($this->xpdo->driver->getPhpType($dbtype), array('string'))) { $charset = ' CHARACTER SET ' . $options['charset']; - if (!empty($options['charset'])) { + if (!empty($options['collation'])) { $charset .= ' COLLATE ' . $options['collation']; } }