Development

#7119 (Impossible to set default database encoding)

You must first sign up to be able to contribute.

Ticket #7119 (reopened defect)

Opened 4 years ago

Last modified 1 year ago

Impossible to set default database encoding

Reported by: theq Assigned to: Jonathan.Wage
Priority: minor Milestone: 1.4.11
Component: configuration Version: 1.4.10
Keywords: doctrine encoding utf8 Cc: hal
Qualification: Unreviewed

Description

When you use doctrine, encoding parametr is ignored and below config cause an error.

# config/database.yml
all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=doctrine'
      username: theq
      password: ********
      attributes:
        default_table_collate: utf8_unicode_ci
        default_table_charset: utf8

When I use "symfony doctrine:rebuild-db" I get this:

Warning: constant(): Couldn't find constant Doctrine::DEFAULT_TABLE_COLLATE_UTF8_UNICODE_CI in /home/theq/Doctrine/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineDatabase.class.php on line 80

Warning: constant(): Couldn't find constant Doctrine::DEFAULT_TABLE_CHARSET_UTF8 in /home/theq/Doctrine/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineDatabase.class.php on line 80

Its connected with http://trac.doctrine-project.org/ticket/2199 but this looks like symfony problem in parsing database.yml configuration file.

Change History

09/09/09 09:15:58 changed by theq

I pinpointed the bug to be in sfDoctrineDatabase class, its trying to change value to constant that doesnt exists in doctrine. If you pass just value it works, but dunno why it was done in a first place.

    foreach ($attributes as $name => $value)
    {
      if (is_string($name))
      {
        $stringName = $name;
        $name = constant('Doctrine::ATTR_'.strtoupper($name));
      }
      if (is_string($value))
      {
        $value = constant('Doctrine::'.strtoupper($stringName).'_'.strtoupper($value));
      }
      $this->_doctrineConnection->setAttribute($name, $value);
    }

09/23/09 09:25:37 changed by fabien

  • owner changed from fabien to Jonathan.Wage.

11/24/09 15:33:57 changed by victor

I propose the following change in order to support charset & collate within sf (that's sfDoctrineDatabase.class.php - l.76 for 1.4RC2)

    foreach ($attributes as $name => $value)
    {
      if (is_string($name))
      {
        $stringName = $name;
        $name = constant('Doctrine_Core::ATTR_'.strtoupper($name));
      }

      if (is_string($value))
      {
        $stringName = strtoupper($stringName);
        $notDoctrine = array('DEFAULT_TABLE_CHARSET', 'DEFAULT_TABLE_COLLATE');
        if (!in_array($stringName, $notDoctrine))
        {
          $value = constant('Doctrine_Core::'.$stringName.'_'.strtoupper($value));
        }
     }

And as a pacth

       if (is_string($value))
       {
-        $value = constant('Doctrine_Core::'.strtoupper($stringName).'_'.strtoupper($value));
-      }
+        $stringName = strtoupper($stringName);
+        $notDoctrine = array('DEFAULT_TABLE_CHARSET', 'DEFAULT_TABLE_COLLATE');
+        if (!in_array($stringName, $notDoctrine))
+        {
+          $value = constant('Doctrine_Core::'.$stringName.'_'.strtoupper($value));
+        }
+     }

11/25/09 15:21:06 changed by nervo

  • version changed from 1.3.x DEV to 1.3.0 RC2.

I can confirm this bug in 1.3RC2 and 1.4RC2.

Something like :

attributes:
        default_table_charset: utf8

is converted in a constant Doctrine_Core::DEFAULT_TABLE_CHARSET_UTF8 which of course does not exists.

I should be Doctrine_Core::DEFAULT_TABLE_CHARSET = 'UTF8'

That makes "attributes" parameter in database.yml unusable.

Sure, we can define them in ProjectConfiguration? class, but it makes sense to group all doctrine parameters in the same place (that is, database.yml)

11/26/09 12:12:03 changed by nervo

#6884 seems to relate the same issue

12/01/09 00:23:44 changed by Jonathan.Wage

  • status changed from new to closed.
  • resolution set to invalid.

You are using the wrong syntax, it should be:

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=doctrine'
      username: theq
      password: ********
      encoding: utf8

Of course you can always do it with PHP code which is the ideal and recommended way.

12/01/09 08:57:15 changed by victor

  • status changed from closed to reopened.
  • resolution deleted.

Jonathan:
"You are using the wrong syntax" -> I am not sure if encoding the "encoding" option allow setting the collation (does not seem to me when I look at sfDoctrineConnectionListener plus does not work when testing)

"you can always do it with PHP" -> Of course we can do everything with PHP but we already have to modify database.yml to set the db name, host, ... and some other "supported" attributes so for the sake of consistency it might be good to add the support those two parameters.

If you don't want to fix it I am pretty sure this defect will re-appear sometime soon. So you would have to document it somewhere and that would take more time than fixing this defect. So please re-consider this defect, you have a working fix attached plus an other one here: http://www.prettyscripts.com/post/230266570/symfony-doctrine-build-all-and-table-collation.

12/01/09 08:59:01 changed by Jonathan.Wage

The attached fix is not a good one. I will see if I can come up with something better. If you look at the patch you will see it is not a good idea.

12/01/09 09:05:26 changed by victor

12/01/09 09:06:22 changed by Jonathan.Wage

No, that is a different issue.

12/01/09 09:16:10 changed by victor

Might be for a different issue but fix this one altogether. You might only want to add some functional test to be completely clean.

12/01/09 12:22:21 changed by theq

AFAIR "encoding: utf8" sets only connection encoding. Thats useless for me cos when I use symfony task to build database I get text fields with latin1 encoding. Anyway I confirm that r24598 fix this bug.

02/20/10 15:17:54 changed by hal

  • cc set to hal.

theq

Just to note, I am using the following syntax in sf1.4, and it works fine:

all:
  mycon1:
    class:  sfDoctrineDatabase
    param:
      dsn:      mysql:dbname=mydb;host=myhost
      username: myuser
      password: mypassword
      encoding: utf8
      attributes:
        DEFAULT_TABLE_TYPE: INNODB
        DEFAULT_TABLE_CHARSET: utf8
        DEFAULT_TABLE_COLLATE: utf8_general_ci

Cheers Hal

04/11/11 15:24:03 changed by ldng

  • version changed from 1.3.0 RC2 to 1.4.10.
  • milestone set to 1.4.11.

No it doesn't. The table and the connection are in UTF-8 butt the database is still created as latin1. Dirty.

SHOW CREATE DATABASE yourdbname;