[DC-1050] Doctrine_Relation_ForeignKey ignores ATTR_COLL_KEY attribute Created: 06/Mar/12  Updated: 03/May/14

Status: Open
Project: Doctrine 1
Component/s: Attributes, Relations
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Uli Hecht Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 64Bit
PHP 5.3
Symfony 1.4


Attachments: Text File ForeignKey.php.patch     Microsoft Word Form01 - Diagnóstico-12012011.doc     File Proposta do sistema de Gestão de ligas.odt     File Proposta do sistema de meio ambiente.odt    

 Description   

Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

$coll = $this->getTable()>getConnection()>query($dql, $id);
$related = $coll[0];

As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

$this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

// program 1:

$m = new Main();
$m->name = 'M1';
$m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
$m->setForeignB(new ForeignB());
$m->save();

// program 2:

$m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
$m->getForeignA()->exists(); // false
$m->getForeignB()->exists(); // true

-------------------------

The big problem about this issue is that behavior is inconsistent. If you don't split the example above into two separate programs/processes you won't have problems, since Doctrine accesses the reference which was stored when calling save().

You will get into trouble using functional tests in Symfony. Since there is only a single process for all requests I wasn't able to reproduce a problem caused by this bug which appeared in the production environment.

-------------------------

Edit:

Doctrine_Connection::queryOne() is affected as well!

A solution is to replace

$coll = $this->getTable()>getConnection()>query($dql, $id);
$related = $coll[0];

by

$related = $this->getTable()>getConnection()>query($dql, $id)->getFirst();



 Comments   
Comment by Uli Hecht [ 07/Mar/12 ]

Suggested patch

Comment by joao guermandi [ 03/May/14 ]

Implementação





[DC-949] (patch)allow Native floats and double precision field types for MySQL, Oracle, Pgsql Created: 09/Dec/10  Updated: 09/Dec/10

Status: Open
Project: Doctrine 1
Component/s: Attributes
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Max Blackmer Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Os Independent, MySQL, Oracle, Postgresql


Attachments: Text File doctrine-1.2-native-float.patch    

 Description   

This creates a new attribute constant Doctrine_Core::ATTR_USE_NATIVE_FLOAT and Doctrine_Core::ATTR_USE_NATIVE_DOUBLE. This will allow the setting of attributes of use_native_float = true and use_native_double = true. With these set to true in MySQL of the generated sql will no longer Make FLOAT(18,2) and will make it just FLOAT that is a true floating point the same thing with DOUBLE except it is now a true double precision floating point.

Proper adjustments are also made to MySQL, Oracle and Postgresql to use native floating point declarations to define both single and double precision floating point data types.

I have attached a patch to fix the floating point field types.



 Comments   
Comment by Max Blackmer [ 09/Dec/10 ]

Quote from MySQL Manual "For maximum portability, code requiring storage of approximate numeric data values should use FLOAT or DOUBLE PRECISION with no specification of precision or number of digits" http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html





[DC-903] Make Doctrine_Record_UnknownPropertyException error more descriptive Created: 28/Oct/10  Updated: 28/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Attributes
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Jason Swett Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 10.10



 Description   

If I have a Doctrine object and I try something like $book->getNonexistantThing(), I always get an error like this:
PHP Fatal error: Class 'Doctrine_Record_UnknownPropertyException' not found in /home/jason/projects/mcif/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record/Filter/Standard.php on line 55

It makes it hard to track down the source of the error. Why not have the error include the offending method call?






[DC-834] When altering an existing column PGSQL can't convert to SERIAL for autoincrement Created: 18/Aug/10  Updated: 18/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Attributes, Migrations
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: webPragmatist Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PostgreSQL 8.4



 Description   

If you have an existing column Postgresql won't allow you to use the type SERIAL for altering the column.

First create a column cat_id on category of integer type. Then run the following migration:

migration.php
    public function up()
    {
        $this->changeColumn('category', 'cat_id', 'integer', '4', array(
             'unsigned' => '',
             'primary' => '1',
             'autoincrement' => '1',
             ));
    }

Instead of using type SERIAL doctrine would have to simply alter the column then add a sequence on it's own.






[DC-388] Conservative loading not working Created: 26/Dec/09  Updated: 27/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Attributes
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Karma Dordrak (Drak) Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Apache 2, MySQL 5.1, PHP 5.2.9, Debian 5



 Description   

Apparently, when setting Doctrine::MODEL_LOADING_CONSERVATIVE things like Doctrine_Core::createTablesFromModels() don't work. Have to enable aggressive model loading. This has been confirmed on the doctrine-user mailing list.

I took a brief look at the code: I may be missing something but it appears there may be a logic difference in the conservative vs. aggressive model loading method. Aggressive loading uses require_once on all files in the model directory and tries to determine the name of the class inside the file (by doing a difference on the loaded classes). This logic makes sense since the class and file name do not have to match.

However, conservative loading just tries to calculate the class name and store it in an array for later loading by the autoloader. This means there is a huge logic difference in behaviour between these two loading methods since the model class files actually must differ depending on case (specifically, the model class file name must follow a specific format to match the actual class name) otherwise the autoload array will never know the correct name of the class.

I would also like to comment that overall, require_once is a poor choice for performance reasons, it's vastly slower than include_once, but overall the logic should better be adjusted to use plain include (if possible), for performance reasons.






[DC-383] Migrations not respecting ATTR_TBLNAME_FORMAT Created: 23/Dec/09  Updated: 28/May/10

Status: Open
Project: Doctrine 1
Component/s: Attributes, Migrations
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Karma Dordrak (Drak) Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Debian 5, Apache 2, PHP 5.2.9, MySQL 5.1


Attachments: Text File migration_table_prefix_doctrine_1.2.patch    

 Description   

I am using Doctrine 1.2.1 and Migrations don't appear to respect Doctrine::ATTR_TBLNAME_FORMAT when creating or dropping tables. This means while models create/drop tables with prefixes migrations don't. Also the migration_version table is created without the prefix too even though it was apparently fixed in DC-245.

I haven't tested but it also probably means other attributes like Doctrine::ATTR_IDXNAME_FORMAT and Doctrine::ATTR_SEQNAME_FORMAT are not obeyed either which makes things a little confusing knowing when to care for prefixes or not.



 Comments   
Comment by Erik Wegner [ 28/May/10 ]

Simple patch to set the table name inside constructor





[DC-1006] Custom geometric query error with orderBy Created: 22/May/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Attributes
Affects Version/s: None
Fix Version/s: 1.2.2

Type: Bug Priority: Minor
Reporter: Leonardo Lazzaro Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 1.4.11 and Doctrine 1.2.4. Ubuntu 11.04 Apache2 with mod php5. php5 version PHP 5.3.5-1ubuntu7.2 with Suhosin-Patch



 Description   

Mi Doctrine_Query with this Geometric Query fails with orderBy , but with where works.

$distance = "glength(linestringfromwkb(linestring(GeomFromText('POINT( ".$object->getLatitude()." ".$object->getLongitude() .")'),l.point))) "

This works:
SomeObjectTable::getInstance()>createQuery()>where($distance.' < ?',0.05 )

But this one fails at version 1.2.4, with older version was working.
SomeObjectTable::getInstance()>createQuery()>where($distance.' < ?',0.05 )->orderBy($distance)

Well the problem is at line 74 of OrderBy.php :
$componentAlias = implode('.', $e);

the rendered query in the distance has some ".", for example:
POINT( -34.470829 -58.5286102)

then the after line 74 in OrderBy tries to search por '58' class.

I manually added to DataDict in Mysql.php the POINT datatype (this fix solve me the problem in older versions of Doctrine).






[DC-852] CLONE -Fix returned type value : SQL integers to PHP integers when getting a value from the database. Created: 01/Sep/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Attributes, Data Fixtures, Native SQL, Query, Record
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi Jon,

I have a request for you to improve Doctrine. When declaring a column as an integer, it seems that Doctrine returns a string when getting the value of that column. For example, if I have a "status" column, which can take 0, 1 or 2 as its value, Doctrine will return these values as string, which is not really logical and returning the good PHP type is the goal of an ORM. I'm fond of the triple equal symbol to test a value and I did not understand why this did not work at start :

// in my myModel class
class myModel extends Doctrine_Record
{
const STATUS_VALIDATED = 1;

public function isValidated()

{ return self::STATUS_VALIDATED === $this->getStatus(); }

}

That's why getStatus() gives me a string instead of an integer, whereas the column is declared as an integer in my schema. I'm forced to cast myself the returned value of getStatus() in my model.



 Comments   
Comment by Enrico Stahn [ 01/Sep/10 ]

Proposal for a solution: http://github.com/estahn/doctrine1/compare/master...DC-852

Comment by Jonathan H. Wage [ 01/Sep/10 ]

So if you enable this attribute you live with the fact that casting a string to an integer that is longer than php max integer will give weird results?

Comment by Enrico Stahn [ 02/Sep/10 ]

i'm far from happy with this solution. if an integer that is greater than php max int gets casted it will be casted into a value of type double. if you enable that attribute only values that could successfully casted into an integer will be casted otherwise an exception will be thrown.





[DC-710] doctrine:build-model does not create phpdoc for doctrine builtin attributes (sluggable, timestampable, id) Created: 29/May/10  Updated: 08/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Attributes
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Kevin Hatry Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When defining a table with actAs attributes (Timestampable, Sluggable, ...) doctrine creates columns in the database and corresponding attributes in the model classes, but the PHPDOC in the model classes does not include getters and setters for these "automatic" attributes.
This is unconvenient when using an IDE as the getter are not present in the auto completion.

The enhancement would be to add the appropriate phpdoc @property tags so that symfony can generate all the @method tags.

see http://trac.symfony-project.org/ticket/8711

Thank you

Kevin Hatry



 Comments   
Comment by Jonathan H. Wage [ 08/Jun/10 ]

I don't think this is a problem that can be patched easily, unfortunately.





[DC-418] Inherited models creating NOT NULL restrictions on their parents Created: 11/Jan/10  Updated: 11/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Attributes, Inheritance, Record, Schema Files
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: luke scott Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux skywalker-9 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 17:01:44 UTC 2009 x86_64 GNU/Linux


Attachments: File sample.yaml    

 Description   

to reproduce, create the yaml included in sample.yaml (Note the not-null columns in each subclass)

if you try to save an OnlineProduct without setting copyright_year, or if you create a print_product without setting website_branding_id, then you will get a not null error.
Inherited tables should be able to set their own NOT NULL columns without affecting other tables in the inheritance tree (should be handled in the preSave() method? or is there another mechanism?)



 Comments   
Comment by luke scott [ 11/Jan/10 ]

YAML format was destroyed during copy & paste!
I'm attaching the sample yaml, instead of including it in the description





[DC-839] Version classes not built for models using package attribute Created: 24/Aug/10  Updated: 08/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: Prasad Gupte Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.2.3 / Symfony 1.4.6



 Description   

For models using the 'package' attribute in the schema definition, the version classes do not get created. However, the version table gets created.

There is no problem during the build, but when loading fixtures, there is a fatal error: Class TaxCodeVersion not found

TaxCode:
package: Masters
tableName: Fin_Tax_Codes
actAs:
Activateable: ~
SoftDelete: ~

  1. Versionable:
  2. tableName: fin_tax_codes_version
    1. versionColumn: version
  3. className: %CLASS%Version
    1. auditLog: true
      Auditable: ~
      Timestampable: ~
      .......


 Comments   
Comment by hetsch [ 08/Mar/11 ]

Same here,

If i use this yaml file:

Page:
actAs:
NestedSet:
hasManyRoots: true
rootColumnName: root_id
Versionable:
versionColumn: version
className: %CLASS%Version
auditLog: true
Timestampable:
created:
name: created_at
type: timestamp
format: Y-m-d H
updated:
name: updated_at
type: timestamp
format: Y-m-d H
I18n:
fields: [name]
columns:
name: string(255)

PageVersion and PageTranslation Models don't get generated if i use 'build-models-yaml'. Have to create the Models manually then it works fine.





[DC-1062] Testing Created: 08/Jan/14  Updated: 08/Jan/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: 1.2.1

Type: Task Priority: Critical
Reporter: Janardan Singh Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None





[DC-922] master-slave replication with i18n behavior Created: 10/Nov/10  Updated: 10/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: husen mankada Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

php 5.3, doctrine 1.2, Symfony 1.4, mysql



 Description   

I'm trying to use sfDoctrineMasterSlavePlugin for database replication with Symfony 1.4 and PHP 5.3. But facing problem while selecting I18n records and receiving "Unknown relation alias Translation" error.

I've also tried same with implementation solution given in master-slave chapter of doctrine cookbook but no success.

Is anyone facing same problem with sfDoctrineMasterSlavePlugin and i18n behavio? Is there any solution of the problem?






[DC-674] NULL Dates are translated to '0000-00-00' after upgrading to 1.2.2 Created: 10/May/10  Updated: 06/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.1, 1.2.2
Fix Version/s: 1.2.1, 1.2.2

Type: Bug Priority: Critical
Reporter: Ville Itämaa Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Zend Framework, Ubuntu 9.10, MySQL



 Description   

Once the upgrade was done from Doctrine 1.2.1 to 1.2.2 we discovered that date related issues started to appear.
With dates that are persisted in DB as NULL are translated to "0000-00-00" when retrieved from DB. This has occurred in multiple places and is quite worrying as there is a lot of dates in our project. This means that everywhere in our codebase where we check a datevalue in our Models is NULL we need also to check for the string literal "0000-00-00".



 Comments   
Comment by Jonathan H. Wage [ 10/May/10 ]

Are you able to reproduce this in a test case?

Comment by Ville Itämaa [ 11/May/10 ]

We reverted to Doctrine 1.2.1 after realising the bug to confirm it was Doctrine 1.2.2 that was the cause for the problem. And as a result the records with NULL dates in the DB became NULL in the Models.
But when using Doctrine 1.2.2, the NULL dates became '0000-00-00' in the Models.
I don't have any other way to reproduce this error.

Comment by Jonathan H. Wage [ 11/May/10 ]

Were you able to identity which changeset it was? You can read about creating test cases here http://www.doctrine-project.org/documentation/manual/1_2/en/unit-testing

So far I am not able to reproduce the error you described.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

I'd like to fix this. Did you ever figure out which changeset introduced the issue? I've been trying to figure it out myself.

Comment by Roland Huszti [ 06/Oct/10 ]

With 1.2.3 this works for me fine with both TIMESTAMP and DATE fields.

YAML

        date_of_birth:
            type: date

BASE MODEL

        $this->hasColumn('date_of_birth', 'date', null, array(
             'type' => 'date',

             // try these two
             // 'notnull' => false,
             // 'default' => null
         ));
YAML

        exported_at:
            type: timestamp(25)
            notnull: false
            default: null

            # in this model I have everything to make sure it accepts and defaults to NULL

BASE MODEL

        $this->hasColumn('exported_at', 'timestamp', 25, array(
             'type' => 'timestamp',
             'notnull' => false,
             'length' => '25',
             ));

You may try adding these to your YAML and (base) models

YAML

    fieldname:
         . . .
        notnull: false
        default: null

BASE MODEL

        $this->hasColumn('fieldname', . . .
             . . .
             'notnull' => false, // <<<<<<<
             // 'default' => null, // <<< maybe, probably not needed
             ));

I hope it helps.





[DC-659] Sluggable behavior does not check uniqueness on insert if a slug is manually set, causing SQL error/crash Created: 01/May/10  Updated: 05/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: Christian Seaman Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

symfony-1.3.4 and doctrine-1.2.2



 Description   

The Sluggable behavior has the following code:

Sluggable.php
    /**
     * Set the slug value automatically when a record is inserted
     *
     * @param Doctrine_Event $event
     * @return void
     */
    public function preInsert(Doctrine_Event $event)
    {
        $record = $event->getInvoker();
        $name = $record->getTable()->getFieldName($this->_options['name']);

        if ( ! $record->$name) {
            $record->$name = $this->buildSlugFromFields($record);
        }
    }

However, this can lead to problems...

If the user incorrectly assigns a duplicate slug to the record then there is no uniqueness checking in doctrine and you get an uncaught SQL error looking something like this:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'my-slug-en_GB' for key 'foo_i18n_sluggable_idx'

If this kind of "don't do a preInsert check if I manunally set the slug" behavior is a FEATURE then it would be best to have an option to allow it to be disabled. If it is a BUG then I would suggest that the preInsert method should be changed to:

Sluggable.php
    /**
     * Set the slug value automatically when a record is inserted
     *
     * @param Doctrine_Event $event
     * @return void
     */
    public function preInsert(Doctrine_Event $event)
    {
        $record = $event->getInvoker();
        $name = $record->getTable()->getFieldName($this->_options['name']);

        if ( ! $record->$name) {
            $record->$name = $this->buildSlugFromFields($record);
        } else { // Still check for slug uniqueness when you insert
            $record->$name = $this->buildSlugFromSlugField($record);
        }
    }

C



 Comments   
Comment by Jonathan H. Wage [ 08/Jun/10 ]

Can you provide your changes as a patch/diff with a test case?

Comment by Christian Seaman [ 05/Oct/10 ]

Hi Jonathan,

I'm not so hot at making patches or test cases, but it should be fairly easy if you know what you're doing...

Just try to create and save two records with the same hard-coded slug and the second one will fail with an ugly MySQL crash.

If you add the lines

        } else { // Still check for slug uniqueness when you insert
            $record->$name = $this->buildSlugFromSlugField($record);

to the Sluggable::preInsert() method then this problem is averted and the test cases will pass.

I have been running with this modification in our production version of Doctrine since I first reported this in May and it all seems to work well.

If you really need me to figure out how to make a patch and test case please re-comment on this ticket and I'll see what I can do when I have some free time.

C





[DC-371] Lazy loading - doctrine makes extra queries into db Created: 19/Dec/09  Updated: 23/Dec/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Documentation, Query, Record
Affects Version/s: 1.2.0-BETA3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Roman Drapeko Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 1.4, Doctrine Version: 1.2.0-BETA3



 Description   

Just downloaded symfony 1.4

First of all I have a query:

$q = \Doctrine_Query::create()
->select('u., ur.')
->from('UserDb u')
->leftJoin('u.RealUserDetailsDb ur')
->leftJoin('u.MockUserDetailsDb um')
->where('u.id = :user_id')
;
$user = $q->fetchOne(array(':user_id' => $uid));

After that I'm accessing the fields of this object:

$userArray = array(
'id' => $this->getUser()->getId(),
'real_user_details_id' => $this->getUser()->getRealUserDetailsId(),
'mock_user_details_id' => $this->getUser()->getMockUserDetailsId(),
'real_user_details' => array(),
'mock_user_details' => array()
);

This is the actual queries into DB:

NR1:
SELECT u.id AS u_id, u.user_real_id AS uuser_real_id, u.user_mock_id AS uuser_mock_id, u2.id AS u2id, u2.nickname AS u2nickname, u2.email AS u2_email FROM user u LEFT JOIN user_real u2 ON u.user_real_id = u2.id LEFT JOIN user_mock u3 ON u.user_mock_id = u3.id WHERE (u.id = :user_id)

NR2:
SELECT u.id AS u_id, u.user_real_id AS uuser_real_id, u.user_mock_id AS u_user_mock_id FROM user u WHERE (u.id = '1') LIMIT 1

As you can see there are TWO queries however there should be only one query. The problem is that u.user_real_id is NULL in database and when I do 'real_user_details_id' => $this->getUser()->getRealUserDetailsId() doctrine does not have enough intelligence to understand that these fields have been already requested in NR1. If I comment this field, everything works well.

SURPRISE!
And now a surprise... if I modify a little bit my first query: ">select('u.')" instead of , ">select('u., ur.*')" it WON'T make TWO queries. It will make ONLY ONE!

As you understand this a very critical bug and of course our system won't go to production with this bug.

P.S. Is it possible to turn off the lazy loading in doctrine?



 Comments   
Comment by Roman Drapeko [ 17/Jan/10 ]

Any comments? Will it be fixed??

Comment by Jonathan H. Wage [ 01/Mar/10 ]

Hi, I'd like to take a look but can you make a failing test case that I can run so that I can see if I can come up with a patch that fixes your case and doesn't break anything else.

Comment by Luke Winiarski [ 01/Jun/10 ]

Hi

I had similar problem but after several hours i did work it out

Try to make get method in your model for getting field which has NULL value in database

public function getUserRealId()

{ return $this->_get("user_real_id", false); }

by making second argument false u force doctrine not to lazy load value and extra sql query is not created

regards

Comment by Jonathan H. Wage [ 08/Jun/10 ]

Has anyone been able to reproduce this in a test case? I am not having much luck so far.

Comment by Gennady Feldman [ 23/Dec/10 ]

I've seen this a ton of times. Basically when it loads related records through the Hydrator using leftJoin() and gets NULLs back. BUT it doesn't save the fact that the related records are NULL. So when you actually do call to getRelated objects it sees that it doesn't have the value cached and runs the query again.

Let me know if I should show you the problem in the Doctrine code base.





[DC-992] I18n - Translated fields are not deleted when record in master table is deleted Created: 03/Apr/11  Updated: 28/Oct/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Thanasis Fotis Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP, xampp 1.7.3 (PHP 5.3.1)



 Description   

I have used I18n behavior for my application using the following:

public function setTableDefinition()
{
        $this->setTableName('products');

        $this->hasColumn('id', 'integer', 4, 
            array('fixed' => true, 
                  'primary' => true, 
                  'autoincrement' => true));

        $this->hasColumn('permalink', 'string', 255,
            array('notnull' => true));
        
        $this->hasColumn('title', 'string', 255, 
            array('notnull' => true));
            
        $this->hasColumn('teaser', 'string', 255, 
            array('notnull' => true));
            
        $this->hasColumn('content', 'clob', 32767);
}

public function setUp()
{   
        $this->actAs('I18n', array(
                'fields' => array('title', 'teaser', 'content')
            )
        );
}

Doctrine has created two tables db named products and products_translation.

Insert and update of the record is working fine but when i perform a deletion of a record, the record is deleted from the products table but the translations stored in products translation table are not deleted.



 Comments   
Comment by Justinas [ 28/Oct/11 ]

if you are not using transaction type tables like innoDB you need to set 'appLevelDelete' => TRUE option for I18n
it's not documented feature as i found out.

$this->actAs('I18n', array(
'fields' => array('title', 'teaser', 'content'),
'appLevelDelete' => TRUE,
)
);





[DC-974] generateFile = true - problematic implementation, see symfony ticket #4522 Created: 17/Feb/11  Updated: 17/Feb/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Georg Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 2
Labels: None
Environment:

symfony



 Description   

see http://trac.symfony-project.org/ticket/4522

When using a behaviour with generateFile=true, som eproblematic issues occur:

Let's take for example i18n:

schema.yml
...
actAs:
fields: [text]
generateFiles: true
generatePath: <?php echo sfConfig::get('sf_lib_dir') ?>/model/doctrine/translations

1) The translation model class and it's base class are not created with generate.php (aka symfony doctrine:build --model), but every time a translation model is used. This is not the expected behaviour, because
a) this makes autoloading these classes impossible.
b) the APC cache always sees a new change time, and recaches the fiels. This results in a quick fragmentation of the cache with segmentation faults in the long run.
2) The permissions for the created files are wrong. Normal executable php scripts should not be writable by the web server (admitting that with the current implementation, this is not problem, because the files are created again for each request)
3) The path is hard coded. This brakes deployment by svn update, and I would prefer not to build models on a production server.

Proposal:

  • generate the files at build model time
  • hopefully find a solution with the path

I realize that most development resources are now in the new doctrine, but this issue (especially the apc fragmentation) is a huge problem for me. If you won't fix it, let me know, then I would try to propose a patch. I checked the code, and the building and behaviour internal part of doctrine are not too well documented, and my patch would be far from perfect.






Non-Equal Nest Relations Not Working - from "Children" side (DC-952)

[DC-958] updating Models with Intra-Table Relations cascades strangely Created: 24/Jan/11  Updated: 27/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Documentation, Nested Set, Relations
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: Daniel Reiche Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3 / symfony 1.4.9



 Description   

Sorry for the lengthy explanation, couldn't make it more straight forward:

I have a model which is similiar to a nestet set but the tree structure needs to overlap:

For Model A, every Object A1 can have multiple descendant objects A2 and in turn can be a descendant of multiple objects A0.

Since I saw no way to do this with Nested-Set Relations (or Equal-Nested-Sets) I have set up my Model like this:

modules:
columns: ..<do not matter>
relations:
Children:
class: modules
refClass: modules_required
Parents:
class: modules
refClass: modules_required

modules_required:
columns: <do not matter here, just 2 foreign key columns>
relations:
Children:
Parents:

I needed to specify the Relations on both tables, to use onDelete/onUpdate CASCADE rules. Generated Models look fine, just as intended.
(Every Class has many Children and has many Parents...)

Now the strange part:
When I update an object of modules (say id=18), Doctrine issues the following queries:
DELETE FROM modules_required WHERE (required_id = ? AND module_id IN (?, ?, ?, ?, ?)) - (18, 25, 26, 32, 34, 35)
// where 25 to 35 are CHILDREN of 18
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (25, 25, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (26, 26, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (32, 32, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (34, 34, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (35, 35, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (25, 25, 12)
//where 10 and 12 are PARENTS of 18
and somewhen, Doctrine encounters an MySQL ERROR because of the previous update marathon:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '25-25' for key 'PRIMARY'

The point is:
1. why is Doctrine trying to create self-referencing relations, and
2. why is it touching the relation at all, when i only did change some text fields in the object?

Is there a better way to solve my problem?



 Comments   
Comment by Daniel Reiche [ 25/Jan/11 ]

forgot to add something: I have done a debug run, to see why these queries are created, when there was no data modified that related to these tables:

Doctrine seems to handle my structure internally as a Nested-Set, although I have not specified an actAs: NestedSet or relations: equal: true statement in the model definition.
Is there a way to prevent symfony from misinterpreting this?

This is not a nested set, as each object can have virtually any other object either as parent or as a child, and additionaly, parent relations can span multiple tree-levels:
Object 2 is parent of Object 3 and 6
Object 3 is parent of Object 4 and 5
Object 4 is parent of Object 6

results in: Object 6 has parents 2 and 4 (where 4 has parent 3 and 3 has parent 2 in turn)

This spanning relations seems to cause the guessed nested set to fail.

I simply wanted to create an m:n Relation using a Reference table and the fact that both m and n are of the same class should not consider doctrine.

Comment by Daniel Reiche [ 26/Jan/11 ]

related to #DC-329:
seems to be the same general problem as described there. Only in DC 1.2.3, doctrine tries to delete every child-relation for some unknown reason.

also the h2aEqualable mentioned there does not work, because it does not prevent symfony from issueing the delete queries. It prevents only the UPDATE-Queries, and thus circumvents the MySQL-Error.

Nevertheless, data is still corrupted after object save, thus not useable in production.





[DC-955] Loading fixtures containing data for Versionable/Searchable Models fails due to Duplicate-Key errors Created: 14/Jan/11  Updated: 14/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Data Fixtures, Import/Export, Searchable
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Daniel Reiche Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.3 / symfony 1.4.9-dev / MySQL 5.0



 Description   

Sample schema:

Blog:
actAs: [Versionable, Searchable]
columns:
id:

{ type: integer, primary: true, autoincrement: true }

name: string
text: text

When dumping data of a schema with Versionable and/or Searchable Behaviour, the dump.yml will contain all data, including the *_version and *_index tables.

Trying to load the same .yml file results in Duplicate-Key constraint violations, as long as the data for the *_version and *_index tables is present.
The import is only successfull, when the data for these tables is discarded.
This leads to the issue, that one can only do a dump-load cycle, when the complete version history of a Model is discarded. Which makes dump-load for such models rather useless.






[DC-899] Expose hardDelete method on node object when SoftDelete behavior is used Created: 22/Oct/10  Updated: 22/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Nested Set
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Fernando Varesi Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MySQL



 Description   

When combining SoftDelete and NestedSet behavior, there's no way of calling hardDelete method on node object. According to documentation, to peform a delete on a nested set, delete should be called in node object, which will call delete method on the object itself.






[DC-880] Versionable + I18n creates additional migration with irrelevant data Created: 06/Oct/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors, I18n, Migrations, Relations
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Thomas Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.2, Symfony 1.4, Diem 5.1, Doctrine 1.2.2



 Description   

First run of generate-migrations-diff and migrate creates 2 migration diff files. First one for new tables, second one for new indexes and foreign keys. Than if I run generate-migrations-diff again another version is created although nothing was changed and following is inside:

  • 1st entry tries to drop a foreign key never been created and not existing in file
  • next entry tries to create a foreign key already existing
  • 3rd entry tries to create an existing index

After a long try and errorI found out that it's only happening with I18n plus Versionable behavior.

As I already have spent much time for a report please have also a look at: http://forum.diem-project.org/viewtopic.php?f=2&t=173&sid=5e0e3349c0e15a169bc9990a3104b3f6#p465

As I'm quite new to Doctrine and Symfony systems I cannot get further, but willing for more investigation if just one could give me a hint where to start.



 Comments   
Comment by Andrew Coulton [ 10/Oct/10 ]

I think this is because the versionable behaviour doesn't define a table name in the Doctrine_Template_Versionable class. As a result, if using model prefixes, the prefixes are not discarded from the table names when the behaviour model classes are built. This means that the tables have different names to what is expected, so they have different index keys, so the indexes are dropped and recreated as part of the migration.

I have committed unit tests and patch for this issue (which applies to Searchable also) to http://github.com/acoulton/doctrine1/tree/DC-880

Comment by Daniele Dore [ 19/Sep/11 ]

I experienced the same problem in the latest version 1.2.4, and the patch proposed by Andrew Coulton solves the problem.
Why the fix is not included in official release?





[DC-878] cannot access the version models using object->CLASSNAMEVersion in v1.2.3 Created: 30/Sep/10  Updated: 07/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Roland Huszti Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP Version 5.2.10-2ubuntu6.5 ; Suhosin Patch 0.9.7 ; Ubuntu 9.10 2.6.31-22-generic x86_64 ; Apache/2.2.12 (Ubuntu) PHP/5.2.10-2ubuntu6.5 with Suhosin-Patch ; Doctrine 1.2.3



 Description   

In Doctrine 1.1 if I said

$vAaaaa = Doctrine::getTable('Aaaaa')->find(1);
print_r( $vAaaaa->AaaaaVersion ); // print_r( $vAaaaa->AaaaaVersion[0]->toArray() );

then I got the corresponding version model/array. Our application is using this nice behaviour at several places. But then the project got upgraded to Doctrine 1.2.3, and since then it dies saying

Unknown record property / related component "UserVersion" on "User" on line 55 of file /home/roland/www/cabcall/library/Doctrine/Doctrine/Record/Filter/Standard.php
#0 /home/roland/www/cabcall/library/Doctrine/Doctrine/Record.php(1395): Doctrine_Record_Filter_Standard->filterGet(Object(User), 'UserVersion')
#1 /home/roland/www/cabcall/library/Doctrine/Doctrine/Record.php(1350): Doctrine_Record->_get('UserVersion', true)
#2 /home/roland/www/cabcall/library/Doctrine/Doctrine/Access.php(72): Doctrine_Record->get('UserVersion')
#3 /home/roland/www/cabcall/application/controllers/TestController.php(12): Doctrine_Access->__get('UserVersion')
#4 /home/roland/www/cabcall/library/Zend/Controller/Action.php(513): TestController->indexAction()
#5 /home/roland/www/cabcall/library/Zend/Controller/Dispatcher/Standard.php(295): Zend_Controller_Action->dispatch('indexAction')
#6 /home/roland/www/cabcall/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#7 /home/roland/www/cabcall/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch()
#8 /home/roland/www/cabcall/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#9 /home/roland/www/cabcall/public/index.php(64): Zend_Application->run()
#10

{main}

Here is the exact example I tried before posting:

Aaaaa:
    tableName: aaaaa
    columns:
        something:
            type: integer(8)
            unsigned: false
            notnull: true
            default: 0
    actAs:
        Versionable:
            versionColumn: version
            className: %CLASS%Version
            auditLog: true
            deleteVersions: true


class AaaaaTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object AaaaaTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('Aaaaa');
    }
}


abstract class BaseAaaaa extends Doctrine_Record
{

    public function setTableDefinition()
    {
        $this->setTableName('aaaaa');
        $this->hasColumn('something', 'integer', 8, array(
             'type' => 'integer',
             'unsigned' => false,
             'notnull' => true,
             'default' => 0,
             'length' => '8',
             ));

        $this->option('type', 'INNODB');
        $this->option('collate', 'utf8_general_ci');
        $this->option('charset', 'utf8');
    }

    public function setUp()
    {
        parent::setUp();
        $versionable0 = new Doctrine_Template_Versionable(array(
             'versionColumn' => 'version',
             'className' => '%CLASS%Version',
             'auditLog' => true,
             'deleteVersions' => true
             ));

        $this->actAs($versionable0);
    }

}


class Aaaaa extends BaseAaaaa
{

}


/*
$vAaaaa = New Aaaaa;
$vAaaaa->something = 1;
$vAaaaa->save();
*/

$vAaaaa = Doctrine::getTable('Aaaaa')->find(1);

print_r( $vAaaaa->AaaaaVersion );



 Comments   
Comment by Roland Huszti [ 01/Oct/10 ]
<?php

class OSS_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
    /**
     * Holds the Doctrine instance
     *
     * @var
     */
    protected $_doctrine;


    public function init()
    {
        // Return Doctrine so bootstrap will store it in the registry
        return $this->getDoctrine();
    }


    public function getDoctrine()
    {
        if ( null === $this->_doctrine )
        {
            // Get Doctrine configuration options from the application.ini file
            $doctrineConfig = $this->getOptions();

            require_once 'Doctrine.php';

            $loader = Zend_Loader_Autoloader::getInstance();
            $loader->pushAutoloader( array( 'Doctrine', 'autoload' ) );
            $loader->pushAutoloader( array( 'Doctrine', 'modelsAutoload' ) );

            $manager = Doctrine_Manager::getInstance();

            $manager->setAttribute( Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE );
            $manager->setAttribute( Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true );
            $manager->setAttribute( Doctrine::ATTR_USE_DQL_CALLBACKS, true );

            $manager->setCollate( 'utf8_unicode_ci' );
            $manager->setCharset( 'utf8' );

            Doctrine::loadModels( $doctrineConfig['models_path'] );

            $db_profiler = new Doctrine_Connection_Profiler();

            $manager->openConnection( $doctrineConfig['connection_string'] );
            $manager->connection()->setListener( $db_profiler );

            $manager->connection()->setCollate('utf8_unicode_ci');
            $manager->connection()->setCharset('utf8');

            Zend_Registry::set( 'db_profiler', $db_profiler );

            $this->_doctrine = $manager;
        }

        return $this->_doctrine;
    }

    /**
     * Set the classes $_doctrine member
     *
     * @param $doctrine The object to set
     */
    public function setDoctrine( $doctrine )
    {
        $this->_doctrine = $doctrine;
    }

}

Comment by Roland Huszti [ 07/Oct/10 ]

To have this very nice and useful feature, I had to add these lines by hand to my audited table's models. Not to the base models, those are overwritten every time you migrate to a new version! Also, in the YAML file you can set the classname to whatever you want, so you need to use the same name in the model, too!

MODEL

class XYZ extends BaseXYZ

{


    public function setUp()

    {

        parent::setUp();

        $this->hasMany('XYZVersion', array( 'local' => 'id', 'foreign' => 'id'));

        // you may get the classname from the model, so then you only need to copy-paste the exact same piece of setUp() code into every model you want to
    }


    . . .

YAML

    actAs:
        Versionable:
            versionColumn: version
            className: %CLASS%Version    # this is the default, User -> UserVersion , Address -> AddressVersion, etc.
            auditLog: true
            deleteVersions: true




[DC-858] Custom Behaviors/Templates cause autoloader errors Created: 04/Sep/10  Updated: 04/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Schema Files
Affects Version/s: 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: apric Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows Vista/7
PHP 5.3.1 - 5.3.3
Zend autoloader
not occuring under Ubuntu 10.05 / MacOSX



 Description   

When emitting Behaviors from schema files (YAML in our case),
Doctrine expects a shortened class name of the behavior (e.g. 'Timestampable') instead of the full class name:
The string 'Doctrine_Template_' is automatically prepended and a check (class_exists()) is made.

This is leading to possible autoloader errors (in our case: Zend autoloader does not find our custom behavior):

YAML:

{{
Person:
actAs: [SoftDelete, My_Doctrine_Template_CustomBehavior]
...
}}

'SoftDelete' is the short class name of 'Doctrine_Template_SoftDelete'.
'My_Doctrine_Template_CustomBehavior' is the full class name and shall not be prefixed with 'Doctrine_Template_'.

The corresponding section responsible for this bug:

File: Doctrine/Import/Builder.php
Lines: 702-704, function emitAssign()

{{
if (class_exists("Doctrine_Template_$name", true))

{ $classname = "Doctrine_Template_$name"; } }}

There is no test whether a full class name is given as $name, so there is no way to add custom behaviors to records without the autoloader checking for a non-existing class and spilling errors/notices.
With the above YAML schema file it would test for class_exists('Doctrine_Template_My_Doctrine_Template_CustomBehavior'), which is obviously not existing.

a quick fix could look like this:

{{
if (strpos($name, '_') === false // is this a shortened name of an original Doctrine behaviour class?
&& class_exists("Doctrine_Template_$name", true)) { $classname = "Doctrine_Template_$name";}}}

Another alternative (but breaking compatability with existing schema files) would be to always use full class names instead of fancy short names.

Interestingly enough, this error is only occuring with Zend autoloader on Windows systems, but can be easily avoided with the fix like suggested above.



 Comments   
Comment by Jonathan H. Wage [ 04/Sep/10 ]

I believe this is because the Zend autoloader does not fail silently by default. I think it can be configured to check if the file exists and not throw any errors.





[DC-825] Versionable does not work with column alias on primary keys [+patch] Created: 13/Aug/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File 0001-TestCase-for-issue-DC-825.patch     Text File 0002-DC-825-fix-generation-of-the-versionable-table.patch     Text File 0003-DC-825-fix-generation-of-model-classes-with-column-a.patch    

 Description   

Using the Versionable behavior on a model which has a column with an alias and which is also primary causes the generation of a wrong version of the versionable table.

Example:

 
ModelFoo:
  model_id as id
  username
  password

Generates tables:
model_foo (model_id, username, password, version)
model_foo_version (id, model_id, userrname, password, version)

It should be:
model_foo (model_id, username, password, version)
model_foo_version (model_id, userrname, password, version)



 Comments   
Comment by Enrico Stahn [ 13/Aug/10 ]

TestCase and Fix
http://github.com/estahn/doctrine1/tree/DC-825

Comment by Enrico Stahn [ 18/Aug/10 ]

The supplied patches are not up-to-date. Pls use http://github.com/estahn/doctrine1/tree/DC-825





[DC-801] Multiple template implementation (setImpl) Created: 28/Jul/10  Updated: 28/Apr/12

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: B. Ariston Darmayuda Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None


 Description   

I feel curios when looking setImpl code on Doctrine. It set like this:

public function setImpl($template, $class)
{
    $this->_impl[$template] = $class;

    return $this;
}

I've made a template:

class PersonTemplate extends Doctrine_Template
{
    public function setTableDefinition() 
    {
        //... Person fields (e.g. name, address, etc.)
    }
}

Now I create 2 class that implement PersonTemplate

class Student extends Doctrine_Record
{
    public function setUp()
    {
        $this->actAs('PersonTemplate');
    }
}
class Teacher extends Doctrine_Record
{
    public function setUp()
    {
        $this->actAs('PersonTemplate');
    }
}

Then I set implementation on Doctrine_Manager:

Doctrine_Manager::getInstance()->setImpl('PersonTemplate', 'Student')->setImpl('PersonTemplate', 'Teacher');

Now isn't it only Teacher record recognized as implementation of PersonTemplate ( when we see from this code: $this->_impl[$template] = $class; )

So how we can implement a template into seperated different doctrine record?



 Comments   
Comment by Richard C. Hidalgo [ 28/Apr/12 ]

As the doc says "Tip The implementations for the templates can be set at manager, connection and even at the table level." it is supposed one can do:

Doctrine_Manager::getInstance()->getTable('Student')->setImpl('PersonTemplate', 'Student');
Doctrine_Manager::getInstance()->getTable('Teacher')->setImpl('PersonTemplate', 'Teacher');

but for me it throws an exception:

"Couldn't find concrete implementation for template PersonTemplate"

thx





[DC-795] Can't mix Soft and Hard deletes. Fix with patch provided. Created: 21/Jul/10  Updated: 21/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: 1.2.2

Type: Bug Priority: Major
Reporter: John Wards Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Mac



 Description   

I reported this bug on the symfony site, but after investigation i have found that it is actually a doctrine SoftDelete issue. http://trac.symfony-project.org/ticket/8898

I have a sandbox replicating the problem here:
http://dl.dropbox.com/u/8354765/sf_sandbox.zip

Run the test:
./symfony test:unit Contact

The issue is I want to hard delete my M-M link table and soft delete the parents. This fails. I believe it is to do with the fact that the relations to the parent are marked as Doctrine_Record::STATE_TCLEAN which when the SoftDelete calls save on the parent object this flag trys to reinsert the relations that it has deleted. Things go very wrong at this point and the connection is rolled back.

The fix I have is the following, not sure what this would do to other things or not as I am not overly familiar with Doctrine internals...

Index: Doctrine/Template/Listener/SoftDelete.php
===================================================================
--- Doctrine/Template/Listener/SoftDelete.php	(revision 12962)
+++ Doctrine/Template/Listener/SoftDelete.php	(working copy)
@@ -95,6 +95,7 @@
     public function postDelete(Doctrine_Event $event)
     {
         if ( ! $this->_options['hardDelete']) {
+            $event->getInvoker()->clearRelated();
             $event->getInvoker()->save();
         }
     }

This works even if the relations have been marked as SoftDelete.



 Comments   
Comment by John Wards [ 21/Jul/10 ]

Formatting

Comment by Jonathan H. Wage [ 21/Jul/10 ]

Does this patch pass the test suite?

Comment by John Wards [ 21/Jul/10 ]

I have run the test suite and got the same 8 failures with and without the patch.

These are the failing tests:
Doctrine_Cache_Apc_TestCase
Doctrine_Cache_Abstract_TestCase
Doctrine_Ticket_1783_TestCase

Anything obvious I need to do to get these working, other than enabling apc...

Comment by John Wards [ 21/Jul/10 ]

It seems to be passing all the tests that have SoftDelete in them however, so I would say that it is working as expected.





[DC-758] CascadeDelete not work properly on Versionable and on the AuditLog Created: 21/Jun/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jaime Suez Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Mac OS X Snow Leopard, LAMP and Macports



 Description   
 
Schema:

Personal:
  actAs:
    Versionable:
      deleteVersions: false
      cascadeDelete: false

When you use this configuration and try to delete one of the record linked with the versionned one, an exception about foreign key is raised because the id of the versioned record has a foreign key to the id of the record.

It's necessary to could work with cascadeDelete: false... because like that it's needed to use softDelete and the deleted record's will be stored on the version table, but with the advantage that you don't have the performance problem of soft delete behaviour.

Thanks!






[DC-648] Behavior geographical generates latitude DOUBLE(18, 2), longitude DOUBLE(18, 2) - it's not exact Created: 24/Apr/10  Updated: 19/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Malcolm Hall Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Doctrine 1.2.2


Attachments: File patch.diff    

 Description   

The problem was already described by another person at http://www.doctrine-project.org/jira/browse/DC-385
and was fixed but now is broken again.

When using the Geographical behaviour in a YML schema the latitude is stored in Mysql as a Double(18,2) instead of a Double as it was in the previous versions. It appears that all doubles in yml are defaulting to (18,2).



 Comments   
Comment by Malcolm Hall [ 24/Apr/10 ]

The problem lies in DataDict/Mysql.php

Previously it was:

case 'double':
return 'DOUBLE';

now it's:

case 'double':
$length = !empty($field['length']) ? $field['length'] : 18;
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine_Core::ATTR_DECIMAL_PLACES);
return 'DOUBLE('.$length.', '.$scale.')';

Perhaps this could be improved so that if there is no length specified it returns just double with no length or scale instead of defaulting to 18, ATTR_DECIMAL_PLACES? I expect that most people that use the double type in yaml wouldn't want only 2 decimals.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

Can you provide a patch that fixes the situation for you? we'll see if that has any breakage of current tests.

Comment by khim tieu-philippe [ 26/Jul/10 ]

I have the same trouble, and I fix it by specified directly the precision of the double into Doctrine_Template_Geographical class.

'type' => 'double(18,8)',

Comment by Janusz Slota [ 08/Nov/10 ]

You can fix it with:
Geographical:
  latitude:
    type: float(18,8)
  longitude:
    type: float(18,8)

instead of:
Geographical: ~

Comment by khim tieu-philippe [ 19/Jan/11 ]

diff on Template/Geographical.php

Hope that could help





[DC-630] Add Undelete functionality to SoftDelete behaviour Created: 15/Apr/10  Updated: 15/Apr/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Harry Birrell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Can an undelete function be added to the Doctrine ORM which will reset deleted_at fields to null and conform to cascade rules (just as the original delete did)?






[DC-553] issue when changing the connection inside Doctrine_Query::preQuery() on a model using a behavior Created: 08/Mar/10  Updated: 19/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: 1.2.1

Type: Bug Priority: Major
Reporter: Lukas Kahwe Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We were following:
http://www.doctrine-project.org/documentation/cookbook/1_1/en/master-and-slave-connections

class MyQuery extends Doctrine_Query
{
// Since php doesn't support late static binding in 5.2 we need to override
// this method to instantiate a new MyQuery instead of Doctrine_Query
public static function create($conn = null)

{ return new MyQuery($conn); }

public function preQuery()
{
// If this is a select query then set connection to one of the slaves
if ($this->getType() == Doctrine_Query::SELECT)

{ $this->_conn = Doctrine_Manager::getInstance()->getConnection('slave_' . rand(1, 4)); // All other queries are writes so they need to go to the master }

else

{ $this->_conn = Doctrine_Manager::getInstance()->getConnection('master'); }

}
}

However we are actually forcing all queries after the first access to the master to be run against the master (including selects). Note the example should probably be changed to use setConnection(). However even when using setConnection() it seems like changing the connection can cause issues when running a select on a model with a behavior (in our case we were using i18n). Therefore we believe there is some issue that is caused through the event system, because otherwise queries work just fine even when changing the connection as per the above described code.

We managed to fix things, by not setting the connection explicitly and instead simply using setCurrentConnection('master'), so the bug does not affect us anymore. However this seems to indicate some issues deep inside the event-behavior-template code.



 Comments   
Comment by Jordi Boggiano [ 08/Mar/10 ]

In case the above post is confusing, note that doing $this->_conn = masterconn worked fine for the INSERT, it just broke when doing a subsequent SELECT of a translateable (I18n behavior) model and its Translation table with the following exception:

Exception (Exception): Unknown relation alias Translation (#0)</h1>thrown in file /Library/WebServer/Documents/liip/infocube/ext/db-doctrine/lib/Doctrine/Relation/Parser.php at line 237
backtrace:
#1 Doctrine_Relation_Parser->getRelation called in file /Library/WebServer/Documents/liip/infocube/ext/db-doctrine/lib/Doctrine/Relation/Parser.php at line 235

Comment by Jonathan H. Wage [ 15/Mar/10 ]

It is hard to understand the issue, can you provide a test case?

Comment by Lukas Kahwe [ 15/Mar/10 ]

We already spend well over 2 hours together on project time to find a work around as noted above and I must admit now our motivation is not so big to dig deeper, especially since we didn't find the cause in this time and have the feeling its pretty impossible to fix without huge risks.

Essentially I think all you need to do to reproduce the issue is use the cookbook code and issue some write query and afterwards do a select on a model that has the translatable behavior. It then gave us the above Exception.

Our code worked slightly different since we did not use a random slave, instead we always used a local slave by default, but the first write and any queries thereafter would get send to the master. The code is public and the diff's show what we had to change to get things working. Note that the slave "localhost" connection was the default connection:
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DQ.php?r1=13118&r2=
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DR.php?r1=13118&r2=

Comment by Lukas Kahwe [ 17/Jun/10 ]

we thought we had the issue fixed but ran into another issue today. we then noticed that the issue goes away if we just copy the $tables property from the old connection to the new connection. there is a getTables() method, but there is only a addTable() method, would be nice to have a addTables() method that is faster. or maybe a switchFrom() method that accepts the old connection and does whatever it needs to.

And again it would be nice to update the cookbook entry.
Here are our updated Doctrine_Query and Doctrine_Record classes:
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DQ.php
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DR.php

Comment by Jordi Boggiano [ 19/Jul/10 ]

We just had another funny debugging session related to this. It turns out that the Table objects have a relation to the connection, and if you query a new model that wasn't initialized yet using ->from(), it works because it just gets the current connection passed. However, if you query a new model within a JOIN, then it apparently takes the connection from the related model you're joining from. In our case, the related model was already initialized but had an instance of the old (slave) connection, and so the new model was initialized using the wrong connection, and then the DQL parser exploded trying to resolve relations.

Long story short, adding $table->setConnection($conn); to all tables while switching to the master connection resolved it. The code is updated and you can still view it at the above URLs, or straight in the SVN repo at http://svn.liip.ch/repos/public/okapi2/ext/db-doctrine/trunk/inc/DQ.php





[DC-485] Limit gets lost when doing self join Created: 08/Feb/10  Updated: 08/Feb/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Pascal Helfenstein Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

os x, snow leopard,


Attachments: File schema.yml    

 Description   

hi doctrine team,
today I encountered a very weird problem when I tried to do a selfjoin on a table. the goal was to list all people that have the same addresses but limit the result to 5

the problem was, that the doctrine split it into 2 querys and first selected the correct address ids with the Limit 5. but in the second query the limit is lost. which gives me more than 5 results if a few people have the same address

the DQL looks like this

$q = DQ::create()
->from('address a INNER JOIN a.shared b ON a.city = b.city AND a.street = b.street')
->innerJoin('b.entity e')
->where('a.entity_id = ? AND a.is_active = ?', array($id, $is_active))
->limit(5)
->offset(0);

SQL looks like this:

SELECT * FROM address a
INNER JOIN address a2 ON ((a.city = a2.city AND a.street = a2.street))
INNER JOIN entity e ON a2.entity_id = e.id
WHERE a.id IN ('5689677') AND (a.entity_id = ? AND a.is_active = ?)

Problem: Limit 5 is gone

expected was something like this:

SELECT *
FROM address a
INNER JOIN address b ON a.city = b.city AND a.street = b.street
INNER JOIN entity e ON b.entity_id = e.id
where a.entity_id = 104294414
limit 5

my temporary solution:

$q = new Doctrine_RawSql();
$q->select('

{b.*}

,

{e.*}

,

{p.*}

');
$q->from('address a INNER JOIN address b ON a.city = b.city AND a.street = b.street
INNER JOIN entity e ON b.entity_id = e.id
INNER JOIN person p ON e.id = p.entity_id');
$q->where('a.entity_id = ? AND a.is_active = ?', array($id, $isActive));
$q->addComponent('a', 'address a');
$q->addComponent('b', 'a.shared b');
$q->addComponent('e', 'b.entity e');
$q->addComponent('p', 'e.person p');
$q->limit($limit);
$q->offset($offset);

my schema.yml is attached, do you need anything else?






[DC-430] I18n and inheritance Created: 15/Jan/10  Updated: 15/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Julien Wadin Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Doctrine 1.2 with Symfony 1.4



 Description   

When using i18n with inheritance, the localizables fields are overrinden by the second deriving class.
So, the translation table is containing only fields from one of the two descending classes.

The yml is below:

User:
columns:
email: string(255)
...

Employer:
inheritance:
extends: User
type: column_aggregation
actAs:
I18n:
fields: [description, company]
columns:
company: string(255)
description: text

Recruiter:
actAs:
I18n:
fields: [position]
inheritance:
extends: User
type: column_aggregation
columns:
position: string(255)






[DC-362] Doctrine fails to create correct table structure if model is named "User" Created: 16/Dec/09  Updated: 08/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Query, Relations
Affects Version/s: 1.2.0-RC1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Michael Henriksen Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Mac OS X 10.6.2 (10C540) (Snow Leopard) with MAMP 1.8 bundle:
PHP Version: 5.2.10,
MySQL Version: 5.1.37



 Description   

When building models and database structure from YAML schema, Doctrine ignores the behaviors and relations on models if it is named "User":

...

User:  
  actAs:
    Timestampable:
    Sluggable:
      unique: true
      fields: username
      canUpdate: true
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    company_id
      type: integer(4)
    timezone_id:
      type: integer(1)
    role_id:
      type: integer(1)
    email:
      type: string(255)
    username:
      type: string(255)
      unique: true
    password:
      type: string(40)
    firstname:
      type: string(255)
    lastname:
      type: string(255)
    last_login:
      type: datetime
  relations:
    Company:
      local: company_id
      foreign: id
    Timezone:
      local: timezone_id
      foreign: id
    Role:
      local: role_id
      foreign: id

...

This creates the following table structure:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `company_id` int(11) DEFAULT NULL,
  `timezone_id` tinyint(4) DEFAULT NULL,
  `role_id` tinyint(4) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  `firstname` varchar(255) DEFAULT NULL,
  `lastname` varchar(255) DEFAULT NULL,
  `last_login` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

The table structure is both missing foreign key constraints to Company, Timezone and Role. It is also missing columns updated_at and created_at for Timestampable behavior. The slug column for Sluggable behavior is missing, as well.

When looking at the BaseUser::setUp() method it looks as it is supposed to:

class BaseUser extends Doctrine_Record
{

    ....

    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Company', array(
             'local' => 'company_id',
             'foreign' => 'id'));

        $this->hasOne('Timezone', array(
             'local' => 'timezone_id',
             'foreign' => 'id'));

        $this->hasOne('Role', array(
             'local' => 'role_id',
             'foreign' => 'id'));

        $timestampable0 = new Doctrine_Template_Timestampable();
        $sluggable0 = new Doctrine_Template_Sluggable(array(
             'unique' => true,
             'fields' => 'username',
             'canUpdate' => true,
        ));
        $this->actAs($timestampable0);
        $this->actAs($sluggable0);
    }

    ....

}

So the only area where it goes wrong, is when generating the queries for creating the model tables. I don't know if the same problem appears with other model names, but it doesn't like models named "User".

If I rename the model to "Person" and rebuild, it all works perfectly as it should.



 Comments   
Comment by Michael Henriksen [ 16/Dec/09 ]

Forgot to mention, that it works perfectly when renaming model to something else than "User"

Comment by Sander [ 08/Jan/10 ]

Have the same problem in 1.2.1 at PostgreSQL 8.4





[DC-325] doctrine pager class with sql server stored procedure Created: 04/Dec/09  Updated: 04/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: khurram Ali Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

php 5.3.0 sql server 2000 symfony 1.2.9



 Description   

i am using doctrine pager class for pagination in symfony but not able to find any help how i can i use it

i am using sql server stored procedures for fetching databasae .

Thnaks

Khurram






[DC-1047] hardDelete not resetting flag if exception is thrown Created: 06/Jan/12  Updated: 06/Jan/12

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Lone Wolf Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File softdelete_exception.patch    

 Description   

To be honest I don't know wich version I have but I believe it to be 1.2.3

The problem is pretty simple, I was trying to do a hardDelete and if it fails I would do a softDelete.
Example

try {
    $record->hardDelete();
}
catch (Exception $e) {
    if ($e instanceof Doctrine_Connection_Mysql_Exception && $e->getPortableCode() == Doctrine_Core::ERR_CONSTRAINT) {
        try {
            $record->delete();
        }
        catch (Exception $e1) {
            throw $e1;
        }
    }
    else {
        throw $e;
    }
}

But when the first exception is thrown from hardDelete() in Doctrine_Template_SoftDelete(line 84) the listener flag for hardDelete is not set to false, so if I try to do the delete, it will still behave as if it was a hardDelete.

The solution would be catch the exception, reset the flag and rethrow it.
Patch attached

Hope this info is enough.






[DC-746] Sluggable canUpdate overridden after subsequent updates Created: 17/Jun/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Adam Benson Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

WAMP stack - PHP 5.3



 Description   

When allowing the user to manually change a slug using 'canUpdate' the slug reverts back to it's default generated value upon subsequent saves. Pre-Update on the Sluggable Listener Template seems to incorrectly decide to regenerate the default value.

Example:

$this->actAs('Sluggable', array('unique'=>true, 'fields'=>array('title'), 'canUpdate'=>true));
$record->description = "An example Item";
$record->title = "Example Title";
$record->save();

echo $record->slug; //"example-title" (Correct)

$record->description = "An example Item";
$record->title = "Example Title";
$record->slug = "custom-slug";
$record->save();

echo $record->slug; //"custom-slug" (Correct - First Save)

$record->description = "An example Item";
$record->title = "Example Title";
$record->slug = "custom-slug";
$record->save();
echo $record->slug; //"example-title" (Incorrect - Subsequent Save. Has regenerated it's default slug and lost the user defined one - even though we have passed the users custom one to the object prior to saving it.).


 Comments   
Comment by Christian Seaman [ 05/Oct/10 ]

As far as I can see this is a problem with the logic in Sluggable::preUpdate() , I recently posted a comment about this here:
http://groups.google.com/group/doctrine-user/browse_thread/thread/d40c6ac733738d4a

In short, I think that the code should be changed from:

Sluggable.php
    public function preUpdate(Doctrine_Event $event)
    {
        if (false !== $this->_options['unique']) {
            $record = $event->getInvoker();
            $name = $record->getTable()->getFieldName($this->_options['name']);

            if ( ! $record->$name || (
                false !== $this->_options['canUpdate'] &&
                ! array_key_exists($name, $record->getModified())
            )) {
                $record->$name = $this->buildSlugFromFields($record);
            } else if ( ! empty($record->$name) &&
                false !== $this->_options['canUpdate'] &&
                array_key_exists($name, $record->getModified()
            )) {
                $record->$name = $this->buildSlugFromSlugField($record);
            }
        }
    }

To this (i.e. remove the canUpdate conditions from the first inner if):

Sluggable.php (modified)
    public function preUpdate(Doctrine_Event $event)
    {
        if (false !== $this->_options['unique']) {
            $record = $event->getInvoker();
            $name = $record->getTable()->getFieldName($this->_options['name']);

            if ( ! $record->$name) { // i.e. remove the other conditions - you should only build the slug from other fields if it's empty
                $record->$name = $this->buildSlugFromFields($record);
            // possibly add an "else if !canUpdate then make sure the old value is preserved" here
            } else if ( ! empty($record->$name) &&
                false !== $this->_options['canUpdate'] &&
                array_key_exists($name, $record->getModified()
            )) {
                $record->$name = $this->buildSlugFromSlugField($record);
            }
        }
    }

I have modified my local version of the Doctrine code to use this modification and it seems to (a) not have the problem you reported above and (b) generally work ok. However, I have not run the test suite against it.

C

Comment by Adam Benson [ 19/Nov/10 ]

Updated affected versions

Comment by Adam Benson [ 19/Nov/10 ]

Thanks for the update Christian, perhaps you could share your fix as a patch?

Comment by Jean-Sébastien GERARD [ 21/Jan/11 ]

Hi, I'm working on a multilingue web portal with Symfony 1.4 and Doctrine 1.2.3, and man, your fix saves my life
I use Sluggable slaved by i18n and without your fix Sluggable simply does not do the job, instead it messes up all slugs when updating, eventually you can't retrieve object anymore based on it. I would not set it as only minor bug ?
thanks, anyway.





[DC-963] Doctrine cache - Salt dissociation Created: 03/Feb/11  Updated: 18/Apr/11

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: Thomas Tourlourat - Armetiz Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Doctrine Cache store data into a persistence storage.

Regarding APC, Doctrine use a share storage.
Doctrine is able to cache SQL from DQL, and DOM from SQL.
To do this, Doctrine create a DQL hash, and store the SQL result refer to the hash.

I'm using a server to host two Doctrine project, a preproduction & production Website. In some case, DQL is the same on both project, but the data model definition isn't.

Preproduction convert DQL to SQL using data model definition, and store the SQL result into APC cache refer to the DQL hash.
Production create a DQL hash, this is the same hash as preproduction.. So production instance use the SQL refer to the preproduction..

I'm not sure about the quality of this explanation... But I can add some information is needed.

The solution of this problem is easy. Just add a SALT to any cache id's. It's a Doctrine_Cache problem, not only a Doctrine_Cache_APC problem..
For Query cache it's not really important because this cache is optional, but for result cache.. It's more critical.
The SALT can be define when instantiate the Doctrine_Cache object, it's just an option..

$cacheDriver = new doctrine_Cache_Apc ();
$cacheDriver->setOption ("salt", "domain.tld");



 Comments   
Comment by Thomas Tourlourat - Armetiz [ 03/Feb/11 ]

to complete this bug, I think it's also a problem on DC 2..

Comment by Jaik Dean [ 18/Apr/11 ]

There is already an (undocumented?) option "prefix" that allows this.

$cacheDriver = new Doctrine_Cache_Apc(array('prefix' => 'MY UNIQUE SALT'));





[DC-644] _getCacheKeys() exhausts memory Created: 22/Apr/10  Updated: 06/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Amir W Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Doctrine is installed as a Symfony plugin. Using the latest Symfony from SVN.



 Description   

My scripts have excessive memory consumption and I've often saw in my logs:

PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 2097152 bytes) in /proj/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Cache/Apc.php on line 111

Looking into the code I've found which function to blame:

protected function _getCacheKeys()
{
$ci = apc_cache_info('user');
$keys = array();

foreach ($ci['cache_list'] as $entry)

Unknown macro: { $keys[] = $entry['info']; ######### THIS IS THE LINE }

return $keys;
}

My server extensively uses APC caching and it's normal to have many cache keys.
Obviously retrieving ALL of them is time and memory consuming.
As I'm not well versed with Doctrine's code, I didn't want to dive further in.

Is there another way to avoid this pitfall?



 Comments   
Comment by Amir W [ 26/Apr/10 ]

Is there any patch that could be provided meanwhile? This is quite a problem on a live website.

Comment by Amir W [ 10/May/10 ]

Is this not a critical issue for Doctrine's cache? It's been up for 2 weeks with not even a comment...

Comment by Jonathan H. Wage [ 10/May/10 ]

Hi, what are you calling that is invoking _getCacheKeys()? The only methods that call it are the deleteBy*() methods. It is expected that these methods have to get the entire list of cache keys from the driver in order to perform the delete by operation. These cache clearing operations should probably be done in the CLI environment where the memory limits are higher. If you want to avoid _getCacheKeys() being invoked, then you must not use the deleteBy*() methods.

Comment by Amir W [ 10/May/10 ]

Thank you for commenting. Yes, I am using deleteByRegex() since I need to expire some result cache entries upon an update operation. What other choice do I have if I wish to keep using the result cache offered by Doctrine? Is there any other mechanism?

Can't _getCacheKeys() be optimized some way?

Comment by Jonathan H. Wage [ 10/May/10 ]

No, it is not able to be optimized anymore. It has to load all the keys into a php array in memory in order to loop over them to compare against the regex. You should probably not be doing cache clearing operations in the browser under apache. If you do, you'll need to raise your memory limit.

Comment by Amir W [ 10/May/10 ]

My code actually had a few of these calls and I've now removed use of the result cache with Doctrine. What you're writing means the result cache is not usable for dynamic websites. IMHO, it's a good practice to cache results and remove them once an update is made to the data (which naturally can happen due to an update from a user). However, if that by itself creates an overload on the server (and as you know even a temporary memory abuse leads to an overload), I cannot see how it can be useful.
Please tell me if you think there's a way the results cache can still be usable for a dynamic website.

Thanks

Comment by Jonathan H. Wage [ 10/May/10 ]

This is the only way to allow more complex delete functionality. How you use it, is not up to us. We intended that cache clearing is done from the command line or in an environment where the memory limit is high enough to be able to load all those keys. It may not be able to be used by everyone, if it is not working for how you are using it then you will need to think of another solution I suppose.

Comment by Amir W [ 10/May/10 ]

Thank you for your response and I'll think of another solution for my application.

I did dive into the code and there's a relevant optimization that could be made.

_getCacheKeys() is actually creating another array for all the cache keys which needlessly increases the memory used.
If the deleteBy*() method would be implemented at the driver level (such as with Apc.php) and not at the general level (Driver.php as it is now) this array would not have to be created. It won't be such a code bloat and would surely lessen memory use.

There could be a way around the problem which also implements another feature I miss with the results cache. By allowing some sort of cache tagging to mark the items that may need to be deleted we could easily delete relevant entries. I'll describe the interface here.

Instead of
$q = $q->useResultCache(true, 86400);

There should be
$q = $q->useTagResultCache('SomeTag', true, 86400);
which does the same PLUS update a cached variable (such as 'Doctrine_Result_Cache_Tag_SomeTag') which references the result cache keys of 'SomeTag'.

We can then easily implement deletion of relevant result cache entries with

deleteByTag('SomeTag')

which would read 'Doctrine_Result_Cache_Tag_SomeTag' to figure out which entries should be removed from the cache.

I'm pretty sure my usage scenario is not marginal but let me know what you think.

Comment by Jonathan H. Wage [ 10/May/10 ]

This is already possible if I understand what you describe.

$q->useResultCache(true, 3600, 'key_to_store_cache_under');

Now you can do:

$cacheDriver->delete('key_to_store_cache_under');

Also what you describe useTagResultCache() and keeping up with our own list of cache keys is the way it used to be and was changed to this after worse performance problems were discovered with that approach.

Comment by Amir W [ 10/May/10 ]

Perhaps I've been misunderstood so I'll try explain from the start.

In my system a few queries do relate to the same pieces of information. That information can be updated by a user and thus I would need to remove anywhere between 0 and 50 related result cache variables. I cannot easily name each and every one of my queries thus giving a specific key name doesn't help. So what I did was to prefix the name of each of the queries to indicate that I'll know how to remove them. I may have thousands of results cached and would need to clear just a few. That's why I use the deleteBy*() which proves to be extremely inefficient as it retrieves ALL the keys in my cache driver and not only the Doctrine related ones.

I really don't know how it has been implemented before but what I suggest wouldn't hurt performance as tagging would be an optional addition managed with another variable. If you think that won't b useful to other Doctrine users, I'll simply implement it for my system.

Thanks

Comment by Jonathan H. Wage [ 10/May/10 ]

I think the best solution is the one you suggested earlier. That each cache driver should directly implement this functionality and bypass the creation of the array. What do you think? It is backwards compatible so that way we can commit it in 1.2.

Comment by Amir W [ 10/May/10 ]

Bypassing the array is a required optimization which is easy to implement but it's not really a solution to the problem I'm facing and I believe is common enough (Zend_Cache for example implements tagging) and need to be offered. As it'll be 2 new functions that will implement tagging only when specifically requested, it'll also be backward compatible. The only thing I'm not sure about is if an implementation of some locking mechanism would be needed for the cached variable which would hold the list of cache keys for a specific tag.

Comment by Jonathan H. Wage [ 10/May/10 ]

Let me know what you come up with and we'll have a look at including it in the next 1.2.x release.

Comment by Amir W [ 16/May/10 ]

Bypassing the extra array is still not good enough and IMHO the whole idea of deleteBy() should NOT be used if many such requests could be made, as is my case.

What I've done now is what I mentioned before with a patch that is quite ugly.

In Doctrine/Query/Abstract.php right after the line

$cacheDriver->save($hash, $cached, $this->getResultCacheLifeSpan());

I've added

                if (!empty($GLOBALS['rcache_users_in_query'])) {
                	MyCache::keepRelatedCacheKey($GLOBALS['rcache_users_in_query'], $hash);
                }

Which saves another cache key which holds the hash tags that would have to be deleted on an update.
My global variable is actually an array as a Doctrine query result may be associated with more than one user and possibly other parameters.
Before calling the $q->execute(), I simply update this variable.

When a user on my system does the update, I then delete all relevant Doctrine keys with something like

		if (is_null($cacheDriver)) $cacheDriver = Doctrine_Manager::getInstance()->getAttribute(Doctrine_Core::ATTR_RESULT_CACHE);
		
		foreach($arKeys as $key) {
			$cacheDriver->delete($key);			
		}

and then delete my other cache key.

This solution works well for me. Sorry I cannot make a nice Doctrine patch for it as I'm not well versed with your code. I still believe it should be supported by Doctrine with an optional extra parameter for $q->useResultCache()

Thanks

Comment by David Abdemoulaie [ 08/Jun/10 ]

Hi Amir,

Zend_Cache does not implement tagging for either APC or Memcached backends, see the documentation. It also likely never will, all requests for this functionality have been closed with Wont Fix.

I don't think the deleteBy methods should have ever been implemented. When initially implemented they cached a "doctrine_cache_keys" variable to store the keys known to Doctrine. This however led to a crippling bug that would crash my production servers after a few hours. Not even a friendly "out of memory" limit, but a slowdown and eventual crash. Please see DDC-460 for details. Note that I don't use the magic delete methods, just simple saves with timeouts and this was affecting me.

I fixed the solution as you've seen using the _getCacheKeys() method. I don't believe this functionality should have ever been added to Doctrine to begin with, but this is what we have to work with. It should be the responsibility of the cache store to handle tagging and such, not poorly hacked on with application code.

As it stands, the current implementation doesn't affect people who aren't even using this functionality, as it should be. As Jon suggested, you shouldn't be using this in the context of a page request. Use a CLI script or work on another solution. Your idea of tracking your keys in application code is a good idea, but it doesn't belong in Doctrine imo.

Comment by Amir W [ 10/Jun/10 ]

Thanks David for your comment.

I agree with you that my implementation should not belong in Doctrine and that tagging should have been a part of the cache backends.

Continuing with the same logic you've presented, deleteBy...() functionality **should be removed** from Doctrine if it causes the system to crash as it does so in an obnoxious way so that it would take too long for most developers to notice this is where the problem lies. It has certainly taken too much of my time and efforts and I'd rather save the pain from others.

Comment by Carsten Henkelmann [ 06/Jul/11 ]

We had the exact same problem. We used a "deleteAll()" of a ApcCache object and ran into the "allowed memory size exhausted" pitfall. We helped ourselves with a new class that extends ApcCache and uses the simpler apc_clear_cache function.

 
namespace Foo\Cache;

class ApcCache extends \Doctrine\Common\Cache\ApcCache
{
    /**
     * Delete all cache entries. Memory saving version...
     *
     * @return bool
     */
    public function deleteAll()
    {
        return apc_clear_cache('user');
    }
}
 
use Foo\Cache\ApcCache as Apc;
...
$this->_apc = new Apc();
$this->_apc->deleteAll();

This doesn't return the ids of the deleted entries like the original function but we don't need that. So this works fine for us.





[DC-999] Query cache key can be incorrectly generated Created: 28/Apr/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Caching, Query
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jakub Zalas Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

1. We have two versions of the application on the same server.
2. Second application has an updated database. New field is added to one of the models.
3. When the second app is hit first, query is stored in APC.
4. First app finds cached query and tries to call it. Exception is thrown as it doesn't know anything about the new field yet.

Situation often happens on shared development machine when one developer adds a field but others don't have in their models yet. It also happens on staging server if it's shared with production.

I suspect it only affects queries without explicitly listed fields.

To quickly fix the issue in my symfony project I extended Doctrine_Cache_Apc to implement namespaces (https://gist.github.com/944524). More appropriate place to fix it would be Doctrine_Query_Abstract::calculateQueryCacheHash().



 Comments   
Comment by Pablo Grass [ 27/Jun/11 ]

Could this be a duplicate of http://www.doctrine-project.org/jira/browse/DC-389 ?
Are you querying a model with a *-to-many relation and applying a limit?

See also http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language:limit-and-offset-clauses:the-limit-subquery-algorithm





[DC-902] Xcache Cache Driver is not documented Created: 26/Oct/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.0-ALPHA1, 1.2.0-ALPHA2, 1.2.0-ALPHA3, 1.2.0-BETA1, 1.2.0-BETA2, 1.2.0-BETA3, 1.2.0-RC1, 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Piotr Leszczyński Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All



 Description   

Xcache Cache Driver is not documented at all. Is it working? Is it stable? Can we use it?






[DC-829] Hydrator/RecordDriver/setLastElement And APC useResultCache Created: 16/Aug/10  Updated: 16/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: PIERRONT Julien Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

1) I have a Query with APC useResultCache with leftJoin between User and Avatar. (With no avatar for this User).
2) I have au Query without APC useResultCache with leftJoin between Gallery, User and Avatar (Same user than 1))

On the first show of my page => OK
On second show of my page (With APC Cache) error when i call user->getGalleries() :

In Hydrator/RecordDriver.php setLastElement()

$coll is instanceOf Doctrine_Null and count($coll) return 1, so => Crash because ->getLast doesn't exist in Doctrine_Null class

If you add in setLastElement() (Before if (count($coll) > 0) ....

if ($coll instanceOf Doctrine_Null)

{ return; }

It's works.






[DC-812] Postgresql and query cache Created: 06/Aug/10  Updated: 06/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: admirau Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Postgresql 8.4, Ubuntu 10.04, PHP 5.3, latest APC and Memcache, Memcached



 Description   

After enabling:

$manager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, $cacheDriver);
(both Memcache and APC)

I get:

Doctrine_Connection_Pgsql_Exception: SQLSTATE[08P01]: <>: 7 ERROR: bind message supplies 8 parameters, but prepared statement "pdo_stmt_00000008" requires 16 in /home/taat/www/library/Doctrine/1.2.2/lib/Doctrine/Connection.php on line 1082

Without the cache everything works OK.
RESULT_CACHE works OK too.

Maybe this may help somehow:
http://bugs.php.net/33886






[DC-390] doctrine_cache_keys bigger than 1mb Created: 30/Dec/09  Updated: 27/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Douglas Yau Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Reference
is referenced by DC-460 Doctrine_Cache_Apc/Core changes in 1.... Closed

 Description   

When multiple projects using doctrine use the same memcached server the doctrine_cache_keys can get bigger then 1mb and php will be throwing warnings telling that the data is too big to be stored by memcached.

I am currently using a workaround, having 1 doctrine_cache_keys per application, on the file Cache/Driver.php i added the following line to the constructor

$this->_cacheKeyIndexKey = 'doctrine_cache_keys_' . md5(Doctrine_Manager::getInstance()->getCurrentConnection()->getOption('dsn'));

but if an application uses more than 1mb en keys then the notice will rise again.



 Comments   
Comment by circlechu [ 13/Jan/10 ]

Why doctrine need to save the keys when it is timeout? I found doctrine will hold the duplicated keys in doctrine_cache_keys map. So this is why it will become more and more bigger. So I think if I remove those duplicated key it will be better? Here is my solution
I add array_unique function to remove all duplicated keys in the map. This method is in the Doctrine_Cache_Driver class.

/**

  • Save a cache key in the index of cache keys
    *
  • @param string $key
  • @return boolean True if successful and false if something went wrong.
    */
    protected function _saveKey($key) { $keys = $this->fetch($this->_cacheKeyIndexKey); $keys[] = $key; $keys=array_unique ($keys); return $this->save($this->_cacheKeyIndexKey, $keys, null, false); }




[DC-389] query cache doesn't cache _isLimitSubqueryUsed Created: 26/Dec/09  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Caching, Query
Affects Version/s: 1.1.5, 1.1.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peter Kovacs Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Postgres db, php5.2, linux



 Description   

The problem is that _isLimitSubqueryUsed is not cached with query cache.
It gets calculated when building query, but when the query is coming
from cache it's not.
Because of this, line 1087 of Query/Abstract.php is never executed,
when coming from cache:
if ($this->isLimitSubqueryUsed() &&
$this->_conn->getAttribute(Doctrine::ATTR_DRIVER_NAME) !==
'mysql')

{ $params = array_merge((array) $params, (array) $params); } Maybe it is on purpose, but I didn't get any answer on the google-groups. Here is a diff I use now: Index: trunk/gui/doctrine-library/Doctrine/Query/Abstract.php =================================================================== --- a/trunk/gui/doctrine-library/Doctrine/Query/Abstract.php +++ b/trunk/gui/doctrine-library/Doctrine/Query/Abstract.php @@ -1286,4 +1286,5 @@ $cached = unserialize($cached); $this->_tableAliasMap = $cached[2]; + $this->_isLimitSubqueryUsed = $cached[3]; $customComponent = $cached[0]; @@ -1346,5 +1347,5 @@ }

  • return serialize(array($customComponent, $componentInfo,
    $this->getTableAliasMap()));
    + return serialize(array($customComponent, $componentInfo,
    $this->getTableAliasMap(), $this->isLimitSubqueryUsed()));
    }


 Comments   
Comment by Pablo Grass [ 27/Jun/11 ]

This still seems to be a problem in version 1.2.4, rendering the query cache unusable for our project.
The suggested fix works fine, and seems to hold litte potential for trouble.

Anyone still listening/reading here? We are aware of the EOL, but would love to produce a test case to anyone ("official") trying to fix this - just not sure if it is still worth bothering...





[DC-1001] Doctrine Caching page does not mention the "prefix" option Created: 29/Apr/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Caching, Documentation
Affects Version/s: None
Fix Version/s: None

Type: Documentation Priority: Minor
Reporter: Arend van Waart Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 1
Labels: None


 Description   

http://www.doctrine-project.org/documentation/manual/1_1/en/caching

When not using a prefix with multiple / yet similay projects a mixup of query caching will occur (for example with sfDoctrineGuard queries). This is very easialy fixed with a prefix - but I only realized after two months - that this feature actually existed. There is no mention of this in the documention.

A mention of the feature

$q = Doctrine_Query::create()
->useResultCache(new Doctrine_Cache_Apc(array('prefix'=>'myproject_')));

Would have helped me and I think it will also help others.



 Comments   
Comment by Pablo Grass [ 27/Jun/11 ]

I concur with Arend - mentioning of 'prefix' in the documentation could make this valuable feature much less of a pain to find...
Still holds true in 1.2. documentation: http://www.doctrine-project.org/projects/orm/1.2/docs/manual/caching/en





[DC-980] Moving all ALTERS queries to the end of generated sql file (task build-sql) Created: 04/Mar/11  Updated: 04/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Cli, Schema Files
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: Sergey Eremenko Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File Export.php    

 Description   

Actual in case of using multi database configuration and foreign keys between them.

Now build-sql task generates SQL query for database by database in alphabetical order. It's ugly when we have multidatabase configuration and foreign keys between their tables. It's impossible to do 'import-sql' without errors beucase foreign keys constrains to nonexisting tables are in next database in order.

I have added some code to strings 1176-...






[DC-981] Class prefix isn't being appended when importing data Created: 04/Mar/11  Updated: 04/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Cli
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Maciej Strzelecki Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Configuration:

Doctrine_Manager::getInstance()->setAttribute(Doctrine_Core::ATTR_MODEL_CLASS_PREFIX, 'Foo_');

Schema:

Bar:
columns:
baz: int

Fixtures:

Bar:
Bar_1:
baz: 1

Error on importing data: "Couldn't find class Bar."

Doctrine should use Foo_Bar class for Bar model instead Bar class.






[DC-935] Doctrine_Task_BuildAllReload does not call generate-models-from-yaml Created: 21/Nov/10  Updated: 21/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Cli
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Brandon Evans Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows Vista 32bit, Apache 2.2.14, PHP 5.3.1


Attachments: Text File DC-935.patch    

 Description   

Doctrine_Task_BuildAllReload never calls generate models-from-yaml. This does not coincide with the logic of Doctrine_Task_BuildAll and Doctrine_Task_BuildAllLoad.

BuildAllReload suggests that it will be building all (everything) and then reloading the database.
But instead it only rebuilds the database and loads data

Doctrine 1.2.3 - BuildAllReload.php
public function __construct($dispatcher = null)
    {
        parent::__construct($dispatcher);

        $this->rebuildDb = new Doctrine_Task_RebuildDb($this->dispatcher);
        $this->loadData = new Doctrine_Task_LoadData($this->dispatcher);
        
        $this->requiredArguments = array_merge($this->requiredArguments, $this->rebuildDb->requiredArguments, $this->loadData->requiredArguments);
        $this->optionalArguments = array_merge($this->optionalArguments, $this->rebuildDb->optionalArguments, $this->loadData->optionalArguments);
    }
    
    public function execute()
    {
        $this->rebuildDb->setArguments($this->getArguments());
        $this->rebuildDb->execute();
        
        $this->loadData->setArguments($this->getArguments());
        $this->loadData->execute();
    }

Instead, I think it would be more efficient and understanding to follow the same logic as build-all and build-all-load by calling drop-db and build-all-load.

Proposed - BuildAllReload.php
public function __construct($dispatcher = null)
    {
        parent::__construct($dispatcher);

        $this->dropDb = new Doctrine_Task_DropDb($this->dispatcher);
        
        $this->buildAllLoad = new Doctrine_Task_BuildAllLoad($this->dispatcher);
        
        $this->requiredArguments = array_merge($this->requiredArguments, $this->dropDb->requiredArguments, $this->buildAllLoad->requiredArguments);
        $this->optionalArguments = array_merge($this->optionalArguments, $this->dropDb->optionalArguments, $this->buildAllLoad->optionalArguments);
    }
    
    public function execute()
    {
        $this->dropDb->setArguments($this->getArguments());
        $this->dropDb->execute();
        
        $this->buildAllLoad->setArguments($this->getArguments());
        $this->buildAllLoad->execute();
    }

I attached a patch with the above changes... I got a little lost in the test area for Doctrine_CLI, so that is not included = )



 Comments   
Comment by Brandon Evans [ 21/Nov/10 ]

Added the proper proposed code this time and also attached patch with better naming.





[DC-865] Models that extend a baseclass other than Doctrine_Record treat that baseclass as if it were a model Created: 11/Sep/10  Updated: 11/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Cli, Import/Export
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: will ferrer Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

XP Windows


Attachments: Text File DC_865_fix.patch    

 Description   

We recently made an extended version of Docrtine_Record which has some functionality that is specific to our project and we switched all our models to use this baseclass by setting the cli option: generate_models_options:baseClassName

We found that when we rebuilt our db this base class was being treated as it were a model (even though its an abstract class). This was causing some errors during our build and a table based on the name of the baseclass was being created.

I tracked the problem down to line 310 of Doctrine_Table where the do loop was only breaking for a class named "Doctrine_Record".

It seemed to make more sense to me to have this loop break for any abstract class, so I copied the technique used to check for abstract classes from Doctrine_Core Line 798. This broke a lot of tests however so due to time constraints I went with a simpler fix – instead I just changed the code that checks if the class is named "Doctrine_Record" to be a regular expression that checks to see if the class name starts with "Doctrine_Record" optionally followed by an underscore + more text in the class name.

This has fixed my issue and should let people make extensions of doctrine record which they can use as a baseclass provided that their class names indicate that they are extending Doctrine_Record.

The only problem I can see arising from this if some users have made models that they have named starting with "Doctrine_Record", but that seems like it would be an odd thing to do so this probably it won't be an issue.

I could however look more closely into detecting abstract classes if this would make my changes significantly more useful.

Please see attached patch.

Will Ferrer



 Comments   
Comment by will ferrer [ 11/Sep/10 ]

Here is the patch





[DC-741] Sort of Migration Class Problem With More Than 9 Classes Created: 16/Jun/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Cli
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Dolly Aswin Harahap Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 10.04, PHP 5.3.2, Doctrine 1.2.2


Attachments: Text File DC-741.patch    

 Description   

I have problem when do a migration with more than 9 classes. (Version1, Version2, Version3, ..., Version10)

php doctrine-cli.php migrate 10

When migration class lower than 10, migration well done.
The migration always return another class, not Version10.

I have do a simple research, and found the problem is on the sort of the class name.
It use SORT_NUMERIC, and it is not suitable to sort them.

So, I change the sort method to Natural Sort, to fix this issue.



 Comments   
Comment by Dolly Aswin Harahap [ 16/Jun/10 ]

Here I attach patch to fix this issue. Please check it.

Comment by Jonathan H. Wage [ 24/Aug/10 ]

I am not able to produce the error, things are always in the correct order. I added a test here: http://trac.doctrine-project.org/changeset/7683

Can you help me with how to reproduce the error?





[DC-357] setting "Doctrine_Core::ATTR_EXPORT" to "Doctrine_Core::EXPORT_TABLES" prevents i18n table creation Created: 14/Dec/09  Updated: 14/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Cli
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Lukas Kahwe Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When I try to prevent foreign key creation (because I am using a mix of MyISAM and InnoDB tables) using the given attribute, I notice that all the translation tables are also not getting created.



 Comments   
Comment by Jonathan H. Wage [ 14/Dec/09 ]

You can use the bit operator with this attribute.

http://www.doctrine-project.org/documentation/manual/1_2/en/configuration#exporting

Comment by Lukas Kahwe [ 14/Dec/09 ]

in that case the bug is bogus .. however the docs should probably make it clear that there are other export modes available, then illustrated atm.





[DC-1035] ORA-01791 due to bad driver name in Doctrine_Adapter_Oracle Created: 01/Sep/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: Jayson LE PAPE Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 64 bits, PHP 5.2.11, Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi, Symfony 1.4.13



 Description   

When i execute this code:

 
$q = Doctrine_Query::create()
            ->from('AGENT ag')
            ->leftJoin('ag.CHANTIER_AGENT cag)
            ->orderBy('ag.nom')
            ->limit(10)
            ->execute();
$q2 = Doctrine_Query::create()
            ->from('AGENT ag')
            ->leftJoin('ag.CHANTIER_AGENT cag)
            ->orderBy('ag.nom')
            ->limit(10)
            ->execute();

Doctrine executes :

 
SELECT a.pk AS a__pk, a.ts AS a__ts, a.ck_agent AS a__ck_agent, a.matricule AS a__matricule, a.nom AS a__nom, 
a.prenom AS a__prenom, a.agent_maitrise AS a__agent_maitrise, c.pk AS c__pk, c.ts AS c__ts, c.ck_chantier_agent AS c__ck_chantier_agent, 
c.ek_chantier AS c__ek_chantier, c.fk_chantier AS c__fk_chantier, c.ek_agent AS c__ek_agent, c.fk_agent AS c__fk_agent 
FROM AGENT a 
LEFT JOIN CHANTIER_AGENT c ON a.ck_agent = c.ek_agent 
WHERE a.ck_agent IN (
SELECT a2.ck_agent FROM ( 
SELECT DISTINCT a2.ck_agent, a2.nom FROM AGENT a2 LEFT JOIN CHANTIER_AGENT c2 ON a2.ck_agent = c2.ek_agent ORDER BY a2.nom ) 
a2 WHERE ROWNUM <= 10) ORDER BY a.nom

SELECT a.pk AS a__pk, a.ts AS a__ts, a.ck_agent AS a__ck_agent, a.matricule AS a__matricule, a.nom AS a__nom, 
a.prenom AS a__prenom, a.agent_maitrise AS a__agent_maitrise, c.pk AS c__pk, c.ts AS c__ts, c.ck_chantier_agent AS c__ck_chantier_agent, 
c.ek_chantier AS c__ek_chantier, c.fk_chantier AS c__fk_chantier, c.ek_agent AS c__ek_agent, c.fk_agent AS c__fk_agent 
FROM AGENT a 
LEFT JOIN CHANTIER_AGENT c ON a.ck_agent = c.ek_agent 
WHERE a.ck_agent IN (
SELECT a2.ck_agent FROM ( 
SELECT DISTINCT a2.ck_agent FROM AGENT a2 LEFT JOIN CHANTIER_AGENT c2 ON a2.ck_agent = c2.ek_agent ORDER BY a2.nom ) 
a2 WHERE ROWNUM <= 10) ORDER BY a.nom

This causes "Oracle DB Error ORA-01791 not a SELECTed expression" because the sql query don't have a2.nom in SELECT DISTINCT and it's indispensable for ORDER BY a2.nom
The problem is caused by the variable $attributes in Doctrine_Adapter_Oracle :

 
protected $attributes = array(Doctrine_Core::ATTR_DRIVER_NAME    => "oci8",
                                  Doctrine_Core::ATTR_ERRMODE        => Doctrine_Core::ERRMODE_SILENT);

The problem is in Query.php line 1417 :

	if ($driverName == 'pgsql' || $driverName == 'oracle' || $driverName == 'oci' || $driverName == 'mssql' || $driverName == 'odbc') {

The driver name declared in Doctrine_Adapter_Oracle not in this conditional.
To resolve this we have to modify the declaration of $attributes in Doctrine_Adapter_Oracle to :

protected $attributes = array(Doctrine_Core::ATTR_DRIVER_NAME    => "oracle",
                                  Doctrine_Core::ATTR_ERRMODE        => Doctrine_Core::ERRMODE_SILENT);

An other problem is probably located at line 1409

 if (($driverName == 'oracle' || $driverName == 'oci') && $this->_isOrderedByJoinedColumn()) {

and 1497

        if (($driverName == 'oracle' || $driverName == 'oci') && $this->_isOrderedByJoinedColumn()) {

if don't correct the declaration of $attributes in Doctrine_Adapter_Oracle.






[DC-1034] ORA-00904 in Doctrine_Connection_Oracle Created: 01/Sep/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: Jayson LE PAPE Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 64 bits, PHP 5.2.11, Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi, Symfony 1.4.13



 Description   

When i execute this code:

 
$q = Doctrine_Query::create()
            ->from('AGENT ag')
            ->leftJoin('ag.CHANTIER_AGENT cag)
            ->orderBy('ag.nom')
            ->limit(10)
            ->offset(10)
            ->execute();

Doctrine executes :

 
SELECT a.pk AS a__pk, a.ts AS a__ts, a.ck_agent AS a__ck_agent, a.matricule AS a__matricule, a.nom AS a__nom, a.prenom AS a__prenom, a.agent_maitrise AS a__agent_maitrise, 
c.pk AS c__pk, c.ts AS c__ts, c.ck_chantier_agent AS c__ck_chantier_agent, c.ek_chantier AS c__ek_chantier, c.fk_chantier AS c__fk_chantier, c.ek_agent AS c__ek_agent, c.fk_agent AS c__fk_agent 
FROM AGENT a 
LEFT JOIN CHANTIER_AGENT c ON a.ck_agent = c.ek_agent 
WHERE a.ck_agent IN 
(SELECT b.ck_agent 
FROM ( SELECT a.*, ROWNUM AS doctrine_rownum 
FROM ( SELECT DISTINCT a2.ck_agent, a2.nom FROM AGENT a2 LEFT JOIN CHANTIER_AGENT c2 ON a2.ck_agent = c2.ek_agent ORDER BY a2.nom ) 
a2 ) 
b 
WHERE doctrine_rownum BETWEEN 11 AND 20) 
ORDER BY a.nom

The problem is in function _createLimitSubquery in Doctrine_Connection_Oracle :

 
                    $query= 'SELECT '.$this->quoteIdentifier('b').'.'.$column.' FROM ( '.
                                 'SELECT '.$this->quoteIdentifier('a').'.*, ROWNUM AS doctrine_rownum FROM ( '
                                   . $query . ' ) ' . $this->quoteIdentifier('a') . ' '.
                              ' ) ' . $this->quoteIdentifier('b') . ' '.
                              'WHERE doctrine_rownum BETWEEN ' . $min .  ' AND ' . $max;

Error occures, because table name is AGENT and Doctrine give the first letter of the table name for identifier.
To correct this. Use more than one letter in the quoteIdentifier.

 
                    $query = 'SELECT '.$this->quoteIdentifier('limb').'.'.$column.' FROM ( '.
                                 'SELECT '.$this->quoteIdentifier('lima').'.*, ROWNUM AS doctrine_rownum FROM ( '
                                   . $query . ' ) ' . $this->quoteIdentifier('lima') . ' '.
                              ' ) ' . $this->quoteIdentifier('limb') . ' '.
                              'WHERE doctrine_rownum BETWEEN ' . $min .  ' AND ' . $max;





[DC-1031] CLONE -Multiple connections and i18n (raised as unresolved - original ticket marked as resolved) Created: 23/Aug/11  Updated: 28/Mar/12

Status: Open
Project: Doctrine 1
Component/s: Connection, I18n
Affects Version/s: 1.2.2, 1.2.3
Fix Version/s: 1.2.3

Type: Bug Priority: Blocker
Reporter: James Bell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MySQL 5.1.37
PHP 5.2.11
symfony 1.2.11 DEV

symfony 1.4.13
PHP 5.3.6
Postgres 8.4.8



 Description   

I used to work with a single database named "doctrine". The query was working properly.

I then decided to use 2 databases so I got my schema like this:

connection: doctrine

Category:
actAs:
I18n:
actAs:
Sluggable:
fields: [name]
Timestampable: ~
fields: [name, description]
columns:
id: ~
name:
type: string(255)
notnull: true
description: string

User:
connection: second
columns:
id: ~
name:
type: string(255)
notnull: true

I did setup my connections in config/databases.yml this way:

all:
doctrine:
// ....
second:
// ....

build-model, build-forms, build-filters and cc got ran. But now, I got an exception saying the "Translation" relation doesn't exist. The Base Models include correctly the bindComponent line:

Doctrine_Manager::getInstance()->bindComponent('Category', 'doctrine');

For now, I managed to kind of fixing it with simply swapping the databases order in my config/databases.yml and it's now working again perfectly.

I forgot to mention that in the CategoryTable when i call $this->getConnection()->getName(), it outputs "second"



 Comments   
Comment by James Bell [ 23/Aug/11 ]

Original issue: DC-363 (http://www.doctrine-project.org/jira/browse/DC-363)

There are some additional comments in there that explain the issue as currently being seen in released versions of Doctrine 1.2. Can I help verify that this is the same ticket?

What is needed to help with debug (in addition to the extra information already provided)?

Comment by Andy.L [ 28/Mar/12 ]

meet the same issue and it really blocked my project, seems no one will maintain 1.x. I'm considering whether to replace symfony 1.4 with 2.0.





[DC-1007] Cannot update a field to NULL with MSSQL connection Created: 25/May/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: guitio2002 Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 32 bits with Apache 2.2.x, PHP 5.2.17, Sql Server 2008, Symfony 1.4.11 and Doctrine 1.2.4



 Description   

When trying to update a field to NULL in a MSSQL database, Doctrine generates the following request:

    UPDATE table SET fieldThatMustBeNull = , anotherField = 'blabla';

therefore generating a syntax error.

A fix would be to override the update method in the Doctrine_Connection_Mssql and add the following behavior:

Doctrine_Connection_Mssql
    public function update(Doctrine_Table $table, array $fields, array $identifier)
    {
        if (empty($fields)) {
            return false;
        }

        $set = array();
        foreach ($fields as $fieldName => $value) {
            if ($value instanceof Doctrine_Expression) {
                $set[] = $this->quoteIdentifier($table->getColumnName($fieldName)) . ' = ' . $value->getSql();
                unset($fields[$fieldName]);
            } else if (is_null($value)) {
                $set[] = $this->quoteIdentifier($table->getColumnName($fieldName)) . ' = NULL';
                unset($fields[$fieldName]);
            } else {
                $set[] = $this->quoteIdentifier($table->getColumnName($fieldName)) . ' = ?';
            }
        }

        $params = array_merge(array_values($fields), array_values($identifier));

        $sql  = 'UPDATE ' . $this->quoteIdentifier($table->getTableName())
              . ' SET ' . implode(', ', $set)
              . ' WHERE ' . implode(' = ? AND ', $this->quoteMultipleIdentifier($table->getIdentifierColumnNames()))
              . ' = ?';

        return $this->exec($sql, $params);
    }





[DC-978] Doctrine_Connection_Mssql dies on modifyLimitSubquery every time Created: 27/Feb/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Andrej Pavlovic Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

windows



 Description   

Looking at the latest version of Doctrine_Connection_Mssql in git repo:
https://github.com/doctrine/doctrine1/blob/b4dc8e66a89a7e17cd195c489b18005e19ca9ea5/lib/Doctrine/Connection/Mssql.php

In Doctrine_Query:getLimitSubquery() there is a call to Doctrine_Connection_Mssql::modifyLimitSubquery().

public function modifyLimitSubquery(Doctrine_Table $rootTable, $query, $limit = false, $offset = false, $isManip = false)
{
	return $this->modifyLimitQuery($query, $limit, $offset, $isManip, true);
}

This in turn calls Doctrine_Connection_Mssql::modifyLimitQuery() wihtout passing the $queryOrigin parameter:

    public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false, $isSubQuery = false, Doctrine_Query $queryOrigin = null)
    {
        if ($limit === false || !($limit > 0)) {
            return $query;
        }

        $orderby = stristr($query, 'ORDER BY');

        if ($offset !== false && $orderby === false) {
            throw new Doctrine_Connection_Exception("OFFSET cannot be used in MSSQL without ORDER BY due to emulation reasons.");
        }
        
        $count = intval($limit);
        $offset = intval($offset);

        if ($offset < 0) {
            throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
        }

        $orderbySql = $queryOrigin->getSqlQueryPart('orderby');
        $orderbyDql = $queryOrigin->getDqlPart('orderby');

        if ($orderby !== false) {
            $orders = $this->parseOrderBy(implode(', ', $queryOrigin->getDqlPart('orderby')));

            for ($i = 0; $i < count($orders); $i++) {
...

From just looking at the above code, the query chokes on the first call to a $queryOrigin method. It seems like there is a lot of missing code here which should work with the $query directly when $queryOrigin is not available...

What is the point of $orderbySql and $orderbyDql variables when they are not used anywhere?

This code looks like it's half way done and untested.






[DC-586] Doctrine outputs invalid SQL when using Limit and Order By conditions in MSSQL Created: 18/Mar/10  Updated: 18/Mar/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Jose Prado Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP
Apache 2.2
PHP 5.3
Doctrine 1.2.1
Symfony 1.4



 Description   

I have a Doctrine model which connects to a MSSQL database. I was trying to run the following query:

$q = Doctrine_Query::create()
    ->select('*')
    ->from('Comment c')
    ->innerJoin('c.RecordType')
    ->innerJoin('c.Department')
    ->limit(10)
    ->orderBy('c.Counter');

The code failed with a SQL Syntax exception so I took a look at the generated query and found the following (SELECT fields shortened for readabilty):

SELECT * FROM (
	SELECT TOP 10 * FROM (
		SELECT TOP 10 [c].[counter] AS [c__counter], [c].[loanid] AS [c__loanid]... ... ...
		FROM comments c
			INNER JOIN [SystemTypes] [s] ON [c].[recordtype] = [s].[code] AND [s].[fieldname] = 'RecordType'
			INNER JOIN [SystemTypes] [s2] ON [c].[department] = [s2].[code] AND [s2].[fieldname] = 'Department'
		ORDER BY [c].[counter]
	) AS [inner_tbl]
	ORDER BY [inner_tbl].[counter] AS [c__counter] DESC
) AS [outer_tbl]
ORDER BY [outer_tbl].[counter] AS [c__counter] ASC

As you can see, the ORDER BY clauses on the inner_tbl and outer_tbl segments have AS clauses which do not belong there. If you fix the ORDER BY statements the query runs just fine.

So I decided to prod around the Mssql.php connection class and found the following:

140 public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false, $isSubQuery = false)
141 {
...
169                    $field_array = explode(',', $fields_string);
170                    $field_array = array_shift($field_array);
171                    $aux2 = preg_split('/ as /', $field_array);
172                    $aux2 = explode('.', end($aux2));
173
174                    $aliases[$i] = trim(end($aux2));
...
232 }

Line 171 seems to be in charge of setting up the orderBy aliases but it is looking for a lower case ' as ' string which doesn't exist in this SQL expression. Changing that to a case insensitive regular expression search seems to fix the problem:

171                    $aux2 = preg_split('/ as /i', $field_array);

Here is the resulting SQL with the change:

SELECT * FROM (
	SELECT TOP 10 * FROM (
		SELECT TOP 10 [c].[counter] AS [c__counter], [c].[loanid] AS [c__loanid]... ... ...
		FROM comments c
			INNER JOIN [SystemTypes] [s] ON [c].[recordtype] = [s].[code] AND [s].[fieldname] = 'RecordType'
			INNER JOIN [SystemTypes] [s2] ON [c].[department] = [s2].[code] AND [s2].[fieldname] = 'Department'
		ORDER BY [c].[counter]
	) AS [inner_tbl]
	ORDER BY [inner_tbl].[c__counter] DESC
) AS [outer_tbl]
ORDER BY [outer_tbl].[c__counter] ASC]

This seems to fix the problem but I don't know if it'll create a regression. It's a start though. Anyone have any thoughts on this?






[DC-1048] MSSQL Connection Created: 16/Jan/12  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Constantine Tkachenko Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Microsoft Windows Server 2008 R2; IIS 7; PHP 2.3.8; Doctrine 1.2.4; Symfony 1.4.16



 Description   

Function spliti(); is deprecated.
It need to be change to (in my own opinion):

$field_array = str_ireplace(' as ', ' as ', $field_array);
$aux2 = explode(' as ', $field_array);

thnx.






[DC-998] MySQL Driver possibly subject to sql injections with PDO::quote() Created: 19/Apr/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.0-ALPHA1, 1.2.0-ALPHA2, 1.2.0-ALPHA3, 1.2.0-BETA1, 1.2.0-BETA2, 1.2.0-BETA3, 1.2.0-RC1, 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Anthony Ferrara Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All



 Description   

Prior to 5.3.6, the MySQL PDO driver ignored the character set parameter to options. Due to MySQL's C api (and MySQLND), this is required for the proper function of mysql_real_escape_string() (the C API call). Since PDO uses the mres() C call for PDO::quote(), this means that the quoted string does not take into account the connection character set.

Starting with 5.3.6, that was fixed. So now if you pass the proper character set to PDO via driver options, sql injection is impossible while using the PDO::quote() api call.

PDO proof of concept
$dsn = 'mysql:dbname=INFORMATION_SCHEMA;host=127.0.0.1;charset=GBK;';
$pdo = new PDO($dsn, $user, $pass);
$pdo->exec('SET NAMES GBK');
$string = chr(0xbf) . chr(0x27) . ' OR 1 = 1; /*';
$sql = "SELECT TABLE_NAME
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_NAME LIKE ".$pdo->quote($string)." LIMIT 1;";
$stmt = $pdo->query($sql);
var_dump($stmt->rowCount());

Expected Result: `int(0)`.
Actual Result: `int(1)`.

There are 2 issues to fix. First, the documentation does not indicate that you can pass the `charset` option to the MySQL Driver. This should be fixed so that users are given the proper option to set character sets.

Secondly, `Connection::setCharset()` should be modified for MySQL to throw an exception, since the character set is only safely setable using the DSN with PDO. This is a limitation of the driver and could be asked as a feature request for the PHP core. Either that, or a big warning should be put on the documentation of the API to indicate the unsafe character set change

Note that this is the same issue reported for Doctrine2 with link: http://www.doctrine-project.org/jira/browse/DBAL-111



 Comments   
Comment by Fabien Potencier [ 23/May/11 ]

Any news on this one? It has been "fixed" in Doctrine2 and must be also fixed in Doctrine1.





[DC-989] Doctrine_Connection::execute() and Doctrine_Connection::exec() fail if Doctrine_Event::skipOperation() is triggered Created: 22/Mar/11  Updated: 22/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: David Dixon Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In order to generate SQL from migrations, an event listener was attached to the migration system to monitor for preQuery and preExec events.

In an attempt to prevent the migration from additionally writing the query to the database, the skipOperation method was triggered, and supposedly allowed for n the execute() and exec() methods of Doctrine_Connection

eg. Doctrine_Connection::execute()
 
$this->getAttribute(Doctrine_Core::ATTR_LISTENER)->preQuery($event);

if ( ! $event->skipOperation) {
    $stmt = $this->dbh->query($query);
    $this->_count++;
}
$this->getAttribute(Doctrine_Core::ATTR_LISTENER)->postQuery($event);

unfortunately setting this option in the event listener breaks execution of the migration system as the $count/$stmtn variables (used in the methods) are no longer defined, triggering E_NOTICE, and the fetch* methods (eg fetchColumn) also break as they are chaining methods without testing for the return. theerfore, even if the $stmnt variable was created as initially null, the system would still throw an E_FATAL as the NULL variable doest provide the ::fetchColumn() methods (etc).

Quite a serious flaw as 2 areas of code do not provide a consistent approach to how to work with events.






[DC-960] Bug in OCI8 adapter's freeCursor function causes exception with HYDRATE_ON_DEMAND Created: 26/Jan/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.0-ALPHA1, 1.2.0-ALPHA2, 1.2.0-ALPHA3, 1.2.0-BETA1, 1.2.0-BETA2, 1.2.0-BETA3, 1.2.0-RC1, 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: vadik56 Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

doctrine, symfony, linux, hpux


Attachments: File closeCursor.diff    

 Description   

oci_free_statement should be changed to oci_cancel inside Doctrine_Adapter_Statement_Oracle::closeCursor(). Otherwise exception is thrown if HYDRATE_ON_DEMAND is used followed by foreach loop.

Doctrine2 should also be affected by this bug.

Change:
public function closeCursor()

{ $this->bindParams = array(); return oci_free_statement($this->statement); }

To:
public function closeCursor()

{ $this->bindParams = array(); return oci_cancel($this->statement); }




[DC-917] Doctrine take wrong connction Created: 05/Nov/10  Updated: 05/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Volodymyr Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I have problems with different connection
i am using doctrine with symfony, and i work with 2 connections
in base class i have bind to my connection

Doctrine_Manager::getInstance()->bindComponent('Datasource', 'doctrine');

symfony generate me

$this->datasources = Doctrine_Core::getTable('datasource')
->createQuery('a')
->execute();

and when i execute it show me error error that can find this table but it take wrong connection

by test i tried to add bind component as datasource (first is lower character and it works pretty cool)

then i change getTable('datasource') => getTable('Datasource') but it doesn't work
then i have added
test function to my datasource table

public static function test()

{ return Doctrine_Query::create()->from("Datasource")->execute(); }

and it works.






[DC-881] Doctrine_Manager::parsePdoDsn() doesn't work properly [+patch] Created: 08/Oct/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Doctrine_Manager::parsePdoDsn('dblib:host=127.0.0.1:1433;dbname=foo') does not return proper results.

patch and test case @ github






[DC-863] Connection.UnitOfWork::buildFlushTree when loading data from yml file, Incorrect ordering of tables by their relations Created: 10/Sep/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection, Data Fixtures
Affects Version/s: 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Ochoo Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

symfony 1.4.6, windows 7, apache2.2, php5.3.3, mySQL 5.1.49-community


Attachments: File schema.yml     File test.yml    

 Description   

I don't know where exactly to start, I'm new here, and i'm not even sure this is a bug. BUT

We have a database structure with most important tables' PK's as string fields, which function as FK on other tables the basic structure is:

Artist
-Album
-Song
-Comments

each artist has multiple songs
each artist has multiple albums
each album has multiple songs that belong to the same artist as the album belongs to
each song has multiple comments

thus, the UnitOfWork - builtFlushTree should generate

[0]=>Artist
[1]=>Album
[2]=>Song
[3]=>Comments

but instead i get:
[0] => Album
[1] => Artist
[2] => Song
[3] => Lyrics

which in turn generates:

QLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`lyrics`.`album`, CONSTRAINT `album_artist_fk_stripped_name_artist_stripped_name` FOREIGN KEY (`artist_fk_stripped_name`) REFERENCES `artist` (`stripped_name`) ON DELETE CASCADE ON UPDATE CASC)
obviously.

I've been going through symfony/doctrine code for a whole day trying to figure out why I can't load-data. in the end i get to this buildFlushTree function.
probably have to go deeper. but so far this is it

PS. It's my decision to use string fields as PK's and FK even though it's a bad practice, but just because it is a bad practice I shouldn't be unable to work with it.



 Comments   
Comment by Ochoo [ 10/Sep/10 ]

found a tiny BUG, submitting the fix.

EDIT: scratch the rest from here.

<!-----------
still, fixing the bug does not resolve the issue
BECAUSE:
the whole logic of ordering the tables is flawed! it can be proved, don't have time to do so. but trying to come up with a fix myself

instead of looping through the tables and then through each tables' related tables, either have a recursive function OR implement user defined array sort function, latter of which seems like the proper and correct way to go
-->

Comment by Ochoo [ 10/Sep/10 ]

unfortunately i'm unable to commit any changes i have made. just me being a newbie, any help is appreciated

Comment by Ochoo [ 10/Sep/10 ]

on UnitOfWork.php of Doctrine ORM 1.2.3
Revision 7684
right after the line 752:
array_splice($flushList, $index, 0, $relatedClassName);
there should be:
$index++;

Comment by atali daoud [ 29/Nov/10 ]

@Ochoo: Even with your bugfix, it doesn't seem to work.

Comment by Ochoo [ 01/Dec/10 ]

thanks atali, i haven't checked it on 1.2.3, just did and you're right. the "bug fix" worked on 1.2.0 but not on 1.2.3. I'm gonna look into it, at least i'll try. but this is a bug right?





[DC-841] Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesInQuery regex failing to replace all '?' instances [patch+] Created: 25/Aug/10  Updated: 05/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Daniel Cousineau Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 3
Labels: None
Environment:

PHP 5.2.11, Apache, Microsoft SQL Server 2005



 Description   

When executing queries with WHERE statements using multiple instances of the "<>" operator (as well as other non =,( symbols inbetween definitions), the method Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesInQuery fails to identify all ? replacements.

In the following piece of code I have a query (trimmed for readability and renamed for privacy) that fails to have all "?" symbols replaced as well as the relevant code from the method mentioned above (minus the return statement) doing a simple demonstration:

<?php 
$query = "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> ? AND [t].[field2] <> ? AND [t].[field2] LIKE ?)";

$params = array(
	"'param1'",
	"'param2'",
	"'param3'"
);


/**
 * Replaces bound parameters and their placeholders with explicit values.
 *
 * Workaround for http://bugs.php.net/36561
 *
 * @param string $query
 * @param array $params
 */
//protected function replaceBoundParamsWithInlineValuesInQuery($query, array $params) {

	foreach($params as $key => $value) {
		if(is_null($value)) {
			$value = 'NULL';
		}
		else {
			//$value = $this->quote($value); //REMOVED AS PRE-ADDED QUOTES TO ABOVE PARAMETER LIST
		}

		$re = '/([=,\(][^\\\']*)(\?)/iU';
		
		$matches = array();
		preg_match($re,$query,$matches);
		
		var_dump($matches); //ADDED FOR DEMONSTRATION

		$query = preg_replace($re, "\\1 {$value}", $query, 1);
		
		var_dump($query); //ADDED FOR DEMONSTRATION
	}

//	return $query;
//
//}

Running this code produces:

array(3) {
  [0]=>
  string(18) "([t].[field1] <> ?"
  [1]=>
  string(17) "([t].[field1] <> "
  [2]=>
  string(1) "?"
}
string(108) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <>  'param1' AND [t].[field2] <> ? AND [t].[field2] LIKE ?)"
array(0) {
}
string(108) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <>  'param1' AND [t].[field2] <> ? AND [t].[field2] LIKE ?)"
array(0) {
}
string(108) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <>  'param1' AND [t].[field2] <> ? AND [t].[field2] LIKE ?)"

Unfortunately the regex will not identify all the ? instances properly in the query when run like preg_match_all(), which was my first idea to fix (pre-identify all ? instances, then go through and replace them).

The only 3 potential solutions I can think of are:

1. Pre-identify all ?'s and note their position in the string, to do this using a much looser regex, then replace all the ?'s found
2. Use a stack a loop and a switch statement to scan for eligible ? replacements. I have some sample code that shows this should work, but performance is not something I have tested.
3. Revert back to the previous behavior. Scanning the changelogs I really don't know where this broke, other than queries that worked prior to 1.2.3 have since broken and this method is the cause.



 Comments   
Comment by Daniel Cousineau [ 25/Aug/10 ]

I am probably way over thinking a solutions, however since I have to run home and don't have time to flesh this out further at the moment, my initial idea is something like this:

<?php 
$query = "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> ? AND [t].[field?] LIKE ? AND [t].[field3] = ?)";

$params = array(
	"'param1'",
	"param2?",
	"'param3'"
);

var_dump($query);

$stack = array();
$stringDelim = array("'", '"');

$i = 0;
foreach( str_split($query) as $char )
{
	switch($char) {
		
		case "[":
			if( !in_array(end($stack), $stringDelim) )
				array_push($stack, $char);
			
			break;
			
		case "]":
			if( end($stack) == "[" ) {
				array_pop($stack);
			} else
				array_push($stack, $char);
				
			break;
		
		case "\"":
		case "'":
			if( end($stack) == $char )
				array_pop($stack);
			else
				array_push($stack, $char);
			
			break;
		
		case "?":
			if( !in_array(end($stack), array_merge($stringDelim, array("[", "]"))) )
			{
				$param = array_shift($params);
				$query = substr_replace($query, $param, $i, 1);
				
				$i += strlen($param) - 1;
				var_dump($query);
			}
			
			
			break;
		
		default:
	}
	
	$i++;
}

var_dump($query);

Which produces

string(131) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> ? AND [t].[field?] LIKE ? AND [t].[field3] = ?)"
string(138) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> 'param1' AND [t].[field?] LIKE ? AND [t].[field3] = ?)"
string(144) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> 'param1' AND [t].[field?] LIKE param2? AND [t].[field3] = ?)"
string(151) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> 'param1' AND [t].[field?] LIKE param2? AND [t].[field3] = 'param3')"
string(151) "SELECT * FROM [table] AS [t] WHERE ([t].[field1] <> 'Testing!?' AND [t].[field2] <> 'param1' AND [t].[field?] LIKE param2? AND [t].[field3] = 'param3')"

Which is what we would expect, as well as it doesn't take into account for newly inserted data containing '?' symbols.

But again this is just playing around with potential solutions.

Comment by Enrico Stahn [ 27/Aug/10 ]

The patch for DC-545 broke some queries or didn't worked at all. Unfortunately there was no Test Case for DC-545.

The patch and a Test Case can be found at: http://github.com/estahn/doctrine1/compare/master...DC-841

Comment by Enrico Stahn [ 02/Sep/10 ]

I made a mistake with github, the updated branch can be found at
http://github.com/estahn/doctrine1/tree/DC-841-2

Comment by Lionel ROTA [ 05/Mar/11 ]

Doesn't work with :

'Test' <> 'Test !?'

The question mark is captured...

This code seems working :

foreach($params as $key => $value) {
  if(is_null($value)) {
    $value = 'NULL';
  }
  else {
    $value = $this->quote($value);
  }

  $re = '/((?:[=<>,\(]|LIKE|IS)[^\\\']*)(\?)/iuU';

  $query = preg_replace($re, "\\1 {$value}", $query, 1);
}




[DC-777] getConnectionForComponent and bindComponent are case sensitive Created: 07/Jul/10  Updated: 07/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Marcel Berteler Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 1.4.x
sfDoctrinePlugin


Attachments: Text File doctrine_manager.patch    

 Description   

When using multiple database connections, the sfDoctrinePlugin for Symfony 1.4.x is case sensitive when looking up the connection for a model / component while the Symfony is not.

This causes code to function correct even when the model names are used in lower case. Once a second connection is configured, the model name is registered in upper case via the base-class (as per the naming convention) causing the wrong connection to be chosen when the model is referenced in lower case.

This:

 
$componentName = 'Country';

$this->_bound[$componentName] = $connectionName;

Will result in no connection found for:

 
$componentName = 'country';

if (isset($this->_bound[$componentName])) {
            return $this->getConnection($this->_bound[$componentName]);
        }

Unless this was purposely designed to be case-sensitive, I think this should be changed to prevent confusion since in general PHP is not case sensitive when dealing with variable names.

This bug is related to http://www.doctrine-project.org/jira/browse/DC-740






[DC-773] Connection::createQuery() can use wrong connection Created: 01/Jul/10  Updated: 01/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Lonny Kapelushnik Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None

Attachments: File DC773TestCase.php     Text File DC_773.patch    

 Description   

Similar to bug DC-437 (http://www.doctrine-project.org/jira/browse/DC-437)
When calling Connection::createQuery() object we use the default connection instead of the connection we have when calling the createQuery() method.



 Comments   
Comment by Lonny Kapelushnik [ 01/Jul/10 ]

Patch and Test Case





[DC-740] issue with multiple connection handling Created: 16/Jun/10  Updated: 16/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2
Fix Version/s: 1.2.2

Type: Bug Priority: Major
Reporter: Ian P. Christian Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 3
Labels: None

Attachments: Text File doctrine_core.patch     Text File doctrine_manager.patch    
Sub-Tasks:
Key
Summary
Type
Status
Assignee
DC-618 [PATCH] Local key relations without m... Sub-task Open Jonathan H. Wage  

 Description   

I've found an issue where doctrine will use the wrong connection for tables under certain conditions.

In a template, I'm doing a $sf_user->hasCredential() - which is causing this to be run in sfGuardSecurityUser,

$this->user = Doctrine::getTable('sfGuardUser')->find($id);

When this execute, the calls find themselves to Doctrine_Manager::getConnectionForComponent($componentName)

This method calls Doctrine_Core::modelsAutoload($componentName);, which fails to load the class, and returns false (no checking is done to see if it should return true).

As this fails to include the sfGuardUser classes wher the component binding goes on, the getTAble call will use the default connection, then create the table fails to use the correct connection

Doctrine_Core::getTable()

return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);

the binding is done after the call to getConectionForComponent, as it's getTable that will ultimately cause the autoloader to pull in the table classes.



 Comments   
Comment by Jonathan H. Wage [ 16/Jun/10 ]

Hmm, why is the autoloading of sfGuardUser failing? I don't understand that part. If it is failing do you get a cannot load class error?

Comment by Ian P. Christian [ 16/Jun/10 ]

The reason no autoload error is throw, is because symfony's autoloader loads the class for you, but it does it at the getTable() call, which as seen below from Doctrine_Core::getTable(), it's proxied though the connection - which is created before the gable is instanced, which of when the file is actaully loaded.

return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);
Comment by Ian P. Christian [ 16/Jun/10 ]

Just to expand on this...

This obviously gets called when a call to getTable is made:

    public function getConnectionForComponent($componentName)
    {
        Doctrine_Core::modelsAutoload($componentName);

        if (isset($this->_bound[$componentName])) {
            return $this->getConnection($this->_bound[$componentName]);
        }

        return $this->getCurrentConnection();
    }

The autoload fails, as you can see from the code...

    public static function modelsAutoload($className)
    {
        if (class_exists($className, false) || interface_exists($className, false)) {
            return false;
        }

        if ( ! self::$_modelsDirectory) {
            $loadedModels = self::$_loadedModelFiles;

            if (isset($loadedModels[$className]) && file_exists($loadedModels[$className])) {
                require $loadedModels[$className];

                return true;
            }
        } else {
            $class = self::$_modelsDirectory . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

            if (file_exists($class)) {
                require $class;

                return true;
            }
        }
        return false;
    }

$_modelsDirectory is never set, and $_loadedModelFiles is an empty array. The $_modelsDirectory, even if set, wouldn't handle loading for plugins, which put their models in places like lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUser.class.php.

Comment by Ian P. Christian [ 16/Jun/10 ]

This was not a problem before r7668 (at least, not for most use cases)....

It used to be that null was passed as the first arg in the D_Query::create() method call, causing the query to figure out itself which connection to use, which was done after the component was bound, so that's fine!

However, the code below is how it is in the current head

    public function createQuery($alias = '')
    {
        if ( ! empty($alias)) {
            $alias = ' ' . trim($alias);
        }

        $class = $this->getAttribute(Doctrine_Core::ATTR_QUERY_CLASS);

        return Doctrine_Query::create($this->_conn, $class)
            ->from($this->getComponentName() . $alias);
    }

Here , the connection of the table (as explained above is previously set incorerctly) is passed to the query.

Comment by Ian P. Christian [ 16/Jun/10 ]

I've found a work around to this, not sure if it's a desirable fix though...

In the project configuration class, I've added this to the setup()


    $this->dispatcher->connect('doctrine.configure', array($this, 'doctrineBinder'));

and the following method is also added, were I'm manually doing my bindings...

  public function doctrineBinder(sfEvent $event)
  {
    $manager = Doctrine_Manager::getInstance();
    $manager->bindComponent('sfGuardUser', 'nosp');
    $manager->bindComponent('Incident', 'nosp');
    $manager->bindComponent('ServiceIp', 'ip');

  }

The overhead here isn't really that high (it just sets an element in the array) - I'd also wonder if a bindComponents($array); should be added to simplify this call, but that's another method.

Comment by Marcel Berteler [ 06/Jul/10 ]

After a long and hard look at the sfDoctrinePlugin and Doctrine code I can to the same conclusion. The Doctrine autoload is not working in sfDoctrinePlugin. I think this is more a sfDoctrinePlugin bug than a Doctrine bug.

Instead of manual binding, a better way is the actually make sure the intended flow of the code is working like it should be.

To be able to use sfDoctrineGuard with multiple connections you need to ensure that the connection name is added to the Schema of sfDoctrineGuard. Once this is done, rebuilding the model will put a bindComponent in the class files.

This works fine if the autoload is working like it should.

To get the autoload to work, you can extend the autoload function of Doctrine_Core in Doctrine:

The Doctrine.php file is empty by default, so its easy to add your code to it (until the problem is fixed without having to edit Doctrine code)

lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine.php:

 
class Doctrine extends Doctrine_Core
{
  public static function modelsAutoload($className)
  {
    sfAutoload::getInstance()->autoload($className);

    parent::modelsAutoload($className);
  }
  
}
Comment by Marcel Berteler [ 06/Jul/10 ]

Sorry... the above does not work.

Doctrine_Core->autoload() is called and not Doctrine->autoload().

sfAutoload::getInstance()->autoload($className);

can be added to Doctrine_Core line 1133

public static function modelsAutoload($className)
    {
        if (class_exists($className, false) || interface_exists($className, false)) {
            return false;
        }

        sfAutoload::getInstance()->autoload($className);
Comment by Marcel Berteler [ 06/Jul/10 ]

Oh, and to make sfDoctrineGuard work properly, you might have to ensure the sfBasicSecurityUser is bound to the correct model.

You can do this in plugins\sfDoctrineGuardPlugin\lib\user\sfGuardSecurityUser.class.php or in apps\xxxxx\lib\myUser.class.php

 
Doctrine_Manager::getInstance()->bindComponent('sfGuardUser', 'connectionName');
Comment by Marcel Berteler [ 07/Jul/10 ]

The patch to Doctrine_Core

This is a hack that only works when used in sfDoctrinePlugin / Symfony

Not intended as the final patch to fix this bug but as a work around to make multiple connections usable.

Comment by Ian P. Christian [ 08/Jul/10 ]

This effects migrations too it seems:

Even doing this:


    $manager = Doctrine_Manager::getInstance();                                                          
    $manager->bindComponent('ChangeRequest', 'nosp');                                                    
    $manager->bindComponent('change_request', 'nosp');                                                   
class Addstatetochangerequest extends Doctrine_Migration_Base                                            
{                                                                                                        
  public function up()                                                                                   
  {                                                                                                      
    $this->addColumn('change_request', 'change_state', 'enum', array('values' => array('draft', 'submitted', 'approved', 'rejected', 'closed')));

This results in:


# ./symfony doctrine:migrate
>> doctrine  Migrating from version 0 to 1
                                                                                                                                                                                    
  The following errors occurred:                                                                                                                                                    
                                                                                                                                                                                    
   - SQLSTATE[42S02]: Base table or view not found: 1146 Table 'nosp_test_radius2.change_request' doesn't exist. Failing Query: "ALTER TABLE change_request ADD change_state TEXT"  

The database attempted to be used there is not the correct one.

Comment by Marcel Berteler [ 27/Sep/10 ]

second required patch to make Symfony work with 2 concurrent databases

Comment by Eugeniy Belyaev [ 21/Oct/10 ]
Another bad way to get it working in symfony:


ProjectConfiguration.class.php
  public function configureDoctrine(Doctrine_Manager $manager)
  {
    $files = sfFinder::type('file')
      ->maxdepth(0)
      ->not_name('*Table.class.php')
      ->name('*.class.php')
      ->in(sfConfig::get('sf_lib_dir') . '/model/doctrine');

    foreach ($files as $file) {
      $class_name = str_replace('.class.php', '', basename($file));
      Doctrine_Core::loadModel($class_name, $file);
    }
  }
Comment by Dean de Bree [ 16/Nov/10 ]

I found that if I changed the getTable function inside the Core.php file it seemed to work. Basically it forces the autoloader to load the object file, and when it does this it runs the bound connection statement to bind a table to a connection.

Core.php
/**
     * Get the Doctrine_Table object for the passed model
     *
     * @param string $componentName
     * @return Doctrine_Table
     */
    public static function getTable($componentName)
    {
        if (!class_exists($componentName)) {
            new $componentName();
        }

        return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);
    }




[DC-668] Call to undefined method Doctrine_Adapter_Mysqli::setAttribute() Created: 06/May/10  Updated: 08/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: nadim Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

windows xp, apache2.2 web server, php5.3.1, doctrine1.2.2, zend framework 1.10.3, mysql 5.1



 Description   

i'm trying to switch to php5.3.1.
using the same connection as before, mysql://, i get

Warning: PDO::__construct() [pdo.--construct]: OK packet 6 bytes shorter than expected in C:\wamp\bin\php\php5.2.9-2\PEAR\Doctrine\lib\Doctrine\Connection.php on line 470

after researching this error, i found out that it is related to the new password in mysql5.
i tried changing the password for the connection, and made sure there is no old_password set in my.ini, without any success.

so i'm trying to connect using mysqli adapter, and now i get this error:
PHP Fatal error: Call to undefined method Doctrine_Adapter_Mysqli::setAttribute() in C:\wamp\bin\php\php5.2.9-2\PEAR\Doctrine\lib\Doctrine\Connection.php on line 496

how can i connect to mysql5.1 with php5.3, and what is the best connection to pick. mysql or mysqli.



 Comments   
Comment by Jonathan H. Wage [ 08/Jun/10 ]

What is Doctrine_Adapter_Mysqli? Is this your own class?





issue with multiple connection handling (DC-740)

[DC-618] [PATCH] Local key relations without modifed fields but with modified relations are not saved Created: 06/Apr/10  Updated: 10/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: Bernhard Schussek Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None

Attachments: File DC618TestCase.php     GIF File directadmin-logo.gif     Text File ticket_dc618.patch    

 Description   

Assume the following test setup:

[Email] * — 1 [Author] 1 — * [Book]

Assume further that you have a new Email, Author and Book object. Email and book have modified fields, author does not, except for the foreign key relation.

Now, when you save the Email object, the related Author is not saved because isModified($deep = false) returns false since no local field is modified. The solution is to pass the parameter $deep = true to isModified().

Patch and test case are attached. No existing test is broken by this fix.

PS: This patch fixes the correlated bug that objects with I18N behaviour are not saved if only their Translation objects are modified, but not their own fields.






[DC-541] MSSQL Server: Enabling MARS prevents the saving of records. Created: 03/Mar/10  Updated: 10/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Connection, Record
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Craig Marvelley Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.1
MSSQL Server 2008
Windows
PHP PDO ODBC


Attachments: File index.php     Text File mssql_transaction.patch    

 Description   

This is related to issue #540. In order to circumvent that issue, I enabled MARS (Multiple Active Result Sets) - now when attempting to save any record the following error results:

Fatal error: Uncaught exception 'Doctrine_Transaction_Exception' with message 'Rollback failed. There is no active transaction.' in C:\www\doctrine\lib\Doctrine\Transaction.php on line 319

This is actually caused by the following MSSQL error:

exception 'Doctrine_Transaction_Exception' with message 'SQLSTATE[42000]: Syntax error or access violation: 3997 [Microsoft][SQL Server Native Client 10.0][SQL Server]A transaction that was started in a MARS batch is still active at the end of the batch. The transaction is rolled back. (SQLExecDirect[3997] at ext\pdo_odbc\odbc_driver.c:247)' in C:\www\doctrine\lib\Doctrine\Transaction.php:212 Stack trace: #0 C:\www\doctrine\lib\Doctrine\Transaction.php(511): Doctrine_Transaction->beginTransaction(NULL) #1 C:\www\doctrine\lib\Doctrine\Connection.php(1377): Doctrine_Transaction->beginInternalTransaction(NULL) #2 C:\www\doctrine\lib\Doctrine\Connection\UnitOfWork.php(64): Doctrine_Connection->beginInternalTransaction() #3 C:\www\doctrine\lib\Doctrine\Record.php(1691): Doctrine_Connection_UnitOfWork->saveGraph(Object(Model)) #4 C:\www\doctrine\tools\sandbox\index.php(83): Doctrine_Record->save() #5

{main}

I haven't worked out what's going on yet, but this blog post may shed some light on it:
http://blogs.msdn.com/cbiyikoglu/archive/2006/11/21/mars-transactions-and-sql-error-3997-3988-or-3983.aspx

I've attached a script to reproduce this issue in the sandbox (MARS is enabled in the DSN).



 Comments   
Comment by Jonathan H. Wage [ 15/Mar/10 ]

We'll need some more information. We don't have a way to test against mssql currently.

Comment by Craig Marvelley [ 16/Mar/10 ]

I've dug a little deeper and it seems that the exception is thrown because the Doctrine_Transaction_Mssql class has overrides for the transaction begin/commit/rollback methods. When I remove these overrides and let transactions be handled through the PDO API I don't get any exceptions while transactions seem to function as normal.

Why are these methods overridden? Is it perhaps only necessary for the MSSQL PDO extension, as suggested here (http://trac.symfony-project.org/wiki/HowToConnectToMSSQLServer), since that extension seemingly has no native transaction support (I've never used it)? Perhaps this isn't necessary for the ODBC extension?

Comment by Craig Marvelley [ 16/Mar/10 ]

This patch maintains the existing manual transaction functionality for MSSQL connections, but uses the native PDO API for ODBC connections.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

Hmm. I don't think this patch is good. It doesn't fix the problem, just hacks around it.

Comment by Craig Marvelley [ 08/Jun/10 ]

Ok.. Do you have any recommendations for a better patch? While I agree my patch is far from elegant, it does at least allow MSSQL and ODBC to work alongside each other. As far as I can tell, the underlying issue is that Doctrine uses the same driver for two very different PDO extensions - I couldn't think of a way to resolve this issue without some kind of check as to which extension is in use.

We could maybe catch the exception that's thrown in the first instance when running a manual query, and try calling the parent rollback method instead? Maybe only when the current connection is ODBC? That's essentially the same approach though, with the added overhead of an unnecessary query that we know will fail..

I'm very keen to find a fix that you're happy with for this since I've been manually patching it for a while, so any feedback that would engender that would be great!

Comment by Jonathan H. Wage [ 08/Jun/10 ]

I am still not sure of the exact problem/error that is happening. When isn't happening with the current code? or is something happening that should not?

Comment by Craig Marvelley [ 09/Jun/10 ]

As far as I understand it (I'm no SQL Server expert, unfortunately!) the issue is this:

The Doctrine_Transaction_Mssql class is used for both the MSSQL and ODBC PDO extensions. It manages transactions by executing manual queries against the database (ROLLBACK TRANSACTION, COMMIT_TRANSACTION, etc.).

This isn't compatible with the ODBC PDO extension and SQL Server when Multiple Active Record Sets is enabled; I believe MARS allows multiple transactions to co-exist, and this query-style way of managing them isn't compatible with that as transactions aren't 'namespaced'. MARS is critical because without it there's no way of looping over more than one record set at the same time, something we take for granted in MySQL et al.

From that link to the Symfony wiki I posted earlier, it appears that the query method of managing transactions is only necessary for the MSSQL PDO extension - quote:

"dblib doesn't support transactions so we need to add a workaround for transactions, last insert ID, and quoting"

This is backed up by the patch - when we let the ODBC driver handle transactions natively, everything works fine.

Does that make sense?

Comment by Jonathan H. Wage [ 09/Jun/10 ]

Now that I look at everything again, do we need to even be overriding those methods at all in Doctrine_Transaction_Mssql (_doRollback, _doCommit, _doBeginTransaction). We should just let the database driver handle it?

Comment by Jonathan H. Wage [ 09/Jun/10 ]

Index: lib/Doctrine/Transaction/Mssql.php
===================================================================
--- lib/Doctrine/Transaction/Mssql.php	(revision 7673)
+++ lib/Doctrine/Transaction/Mssql.php	(working copy)
@@ -65,28 +65,4 @@
 
         $this->conn->execute($query);
     }
-    
-    /**
-     * Performs the rollback.
-     */
-    protected function _doRollback()
-    {
-        $this->conn->getDbh()->exec('ROLLBACK TRANSACTION');
-    }
-    
-    /**
-     * Performs the commit.
-     */
-    protected function _doCommit()
-    {
-        $this->conn->getDbh()->exec('COMMIT TRANSACTION');
-    }
-    
-    /**
-     * Begins a database transaction.
-     */
-    protected function _doBeginTransaction()
-    {
-        $this->conn->getDbh()->exec('BEGIN TRANSACTION');
-    }
 }

It seems like we don't even need to do that?

Comment by Craig Marvelley [ 10/Jun/10 ]

For ODBC, we definitely don't. That link suggests the above approach caters to the MSSQL extension. I've not tried that one because I'm on Windows and as you probably know it's not recommended; I imagine I'd have way too many other problems were I to try! I didn't want to break anything for anyone using the MSSQL driver though, which led to my awkward patch.

From my point of view, I'd imagine the majority of people using SQL Server will be using a Windows stack, and therefore ODBC (and possibly the new SQL Server Driver for PHP PDO extension, which definitely won't need manual queries, in future) - so I'd favour an approach that didn't compromise those drivers.

As an aside - are there any plans afoot to support the new Microsoft endorsed driver? I imagine if you guys were to do so it would be for Doctrine 2, but do you know of any community effort to get it working in 1.2?





[DC-509] Oracle don't close cursor Created: 18/Feb/10  Updated: 28/Jul/11

Status: Reopened
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: oxman Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.1



 Description   

When you doing a big loop of insertion you have a "too many open cursor".
The problem is in Doctrine_Connection class
At line 1005 you should replace :
$stmt = $this->prepare($query);
by
$stmt = $this->dbh->prepare($query);

and at line 1041 you should replace :
$stmt = $this->prepare($query);
by
$stmt = $this->dbh->prepare($query);

After this correction, you never have the problem "too many open cursor"

Thanks to Ota to point that on google groups.
http://groups.google.com/group/doctrine-user/browse_thread/thread/fe6cd03c8fb18b64/728ec1b4e42b1f0b?lnk=gst&q=doctrine_oracle_adapter#728ec1b4e42b1f0b



 Comments   
Comment by Jonathan H. Wage [ 02/Mar/10 ]

Hmm. This change is invalid because it then doesn't return the proper statement object. What is the real issue we get the too many cursors open error?

Comment by oxman [ 04/Mar/10 ]

Why ?
The both return Doctrine_Adapter_Statement_Interface

Comment by Jonathan H. Wage [ 04/Mar/10 ]

The change makes it so they return PDOStatement, and we need it to return the Doctrine statement wrapper, right?

Comment by oxman [ 04/Mar/10 ]

It seems not.

At line 1005 in Doctrine/Connection.php :
$stmt = $this->dbh->prepare($query);
var_dump(get_class($stmt));
die;

I see :
string(33) "Doctrine_Adapter_Statement_Oracle"

And with :
$stmt = $this->prepare($query);
var_dump(get_class($stmt));
die;

I see :
string(29) "Doctrine_Connection_Statement"

The both implements Doctrine_Adapter_Statement_Interface

Comment by vincent [ 29/Apr/10 ]

I have this problem in Symfony 1.4.3 when I use comand:
symfony doctrine:data-load

I have 3000 - 4000 lines in my fixtures and max open cursor at 300 on my database oracle.

This problem can an issue???

Comment by Jonathan H. Wage [ 08/Jun/10 ]

I see, well the change still is not right because it bypasses all the logic in Doctrine_Connection::prepare() which is for sure required and can't just be removed. We need to determine the real issue here in order to properly patch it.

Comment by Peter Wooster [ 29/Jun/10 ]

I'm encountering the same ORA-1000 problem running the symfony doctrine:build-schema command. We are still using PDO, but I have asked in the users group if that's the best choice. The problem is that the listTableColumns and listTableRelations methods both leave a cursor open. They both call Connection::fetchAssoc, so they should be reading all the records.

I narrowed it down a little:

This works properly when no parameters are provided:

$sql = "SELECT * FROM all_tab_columns tc WHERE tc.table_name = 'DEAL'";
$result = $connection->fetchAssoc($sql, array());

This doesn't release the cursor when a named parameter is provided

$sql = "SELECT * FROM all_tab_columns tc WHERE tc.table_name = :tn";
$result = $connection->fetchAssoc($sql, array(':tn' => 'DEAL')); // doesn't release cursor

This doesn't release the cursor when a positional parameter is provided

$sql = "SELECT * FROM all_tab_columns tc WHERE tc.table_name = ?";
$result = $connection->fetchAssoc($sql, array('DEAL')); // doesn't release cursor

This works properly when the PDO connection is used directly

$sql = "SELECT * FROM all_tab_columns tc WHERE tc.table_name = :tn";
$dbh = $connection->getDbh();
$stmt = $dbh->prepare($sql);
$stmt->execute(array(':tn' => 'DEAL'));
$result = $stmt->fetchAll();

Comment by Clément Herreman [ 28/Jul/11 ]

As I went through this bug, I looked for a fix. I found one here https://github.com/derflocki/doctrine1/commit/47b926a523f9f6e3b88042ef2939af0646285ea2

Basically it consist of freeing cursors that aren't used by a SELECT query, thus preventing Oracle from throwing an exception on batch insert/delete.





[DC-375] Doctrine_Table getTable singleton issue Created: 22/Dec/09  Updated: 22/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.0.14
Fix Version/s: None

Type: Bug Priority: Major
Reporter: ben bi Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

symfony 1.2.9



 Description   

first, i defined a table class :
class CohibaClientTable extends Doctrine_Table
{
public $_pager;

public function getAbstractList($arrParam = array(), $page=1, $maxPerPage=20)
{
$objQuery = $this->createQuery('t1')
->select('t1.*');

if(is_array($arrParam) && count($arrParam)>0)

{ QueryAssistant::processOption($objQuery, $arrParam); // dont set "offset" and "limit" option in it }

$this->_pager = new Doctrine_Pager($objQuery, $page, $maxPerPage);

$items = $this->_pager->execute();

$objQuery->free();
return $items;
}

public function getList($page=1, $maxPerPage=20)

{ $arrParam = array( 'orderBy'=>'t1.cle asc' ); return $this->getAbstractList($arrParam, $page, $maxPerPage); }

public function getPager()

{ return $this->_pager; }

}

and then, in the action, invoke it like this codes:
1>
$items = Doctrine::getTable("CohibaClient")->getList(1, $maxPerPage);
$pager = Doctrine::getTable("CohibaClient")->getPager();

$this->log("total records: ".$pager->getNumResults()." total page: ".$pager->getLastPage()."\n");
$lastPage = $pager->getLastPage();
2>
$table = Doctrine::getTable("CohibaClient");
$items = $table->getList(1, $maxPerPage);
$pager = $table->getPager();

$this->log("total records: ".$pager->getNumResults()." total page: ".$pager->getLastPage()."\n");
$lastPage = $pager->getLastPage();

#2 works, but not #1, error is "Fatal error: Call to a member function getNumResults() on a non-object in.... " is it an issue when singleton generation?






[DC-355] Call to a member function evictAll() if a table is retrieved, that is not existent Created: 12/Dec/09  Updated: 12/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.0, 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: aNj Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 8.04



 Description   

Hi!

Im not quite sure it this bahaviour is wanted, but i think that this
should be catched:

If i call Doctrine::getTable on a non existing model, the exception is
thrown. After them i want always to clear all Record Repositories, see
code:

try

{ $table = Doctrine::getTable('notexistent'); }

catch(Exception $e)

{ echo 'not existent'.$e->getMessage(); }

Doctrine_Manager::connection()->clear();

Then I get the error message:

Fatal error: Call to a member function evictAll() on a non-object in /
core/lib/Doctrine/Doctrine/Connection.php on line 1239

The problem is that the function clear doesnt check if a repository is
given.

public function clear()
{
foreach ($this->tables as $k => $table)

{ $table->getRepository()->evictAll(); // getRepository delivers FALSE $table->clear(); }

}

Is it normal behaviour? Or should it be checked first:

if ($repository = $table->getRepository())

{ $repository->evisctAll(); }

best regards,
aNj






[DC-370] Doctrine serializes arrays, objects, etc. like 'string', which is never bigger than a TEXT, limited to 65535 characters (in MySQL) Created: 19/Dec/09  Updated: 29/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Tom Boutell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Doctrine supports storing objects and arrays, and implements this via serialize().

However in DataDict/Mysql they are handled like the 'string' type, which means they are subject to the rules there that ensure nothing bigger than a 'TEXT' is ever used to represent them.

TEXT is not a great choice for objects and arrays because it's difficult to ensure they will not exceed 65,535 bytes in size.

This would be most easily fixed by moving them to the next block of case statements there, used for CLOBs. The logic there already picks suitable large types (MEDIUMTEXT and LONGTEXT) as needed, and defaults to LONGTEXT which is a good choice for objects and arrays.



 Comments   
Comment by David Abdemoulaie [ 29/Jan/10 ]

Array and Object data types now behave identically to clob.

See r7077

Comment by Tom Boutell [ 29/Jan/10 ]

Thanks David!





[DC-280] Add pre/postHydrateResultSet() events Created: 23/Nov/09  Updated: 08/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Connection, Query, Record
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Adam Jensen Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Over the last several weeks I've been working on streamlining the access control logic in the application I'm working on, and I realized that Doctrine's event listeners might be able to help. For more detailed background information take a look at http://groups.google.com:80/group/dallasphp/browse_thread/thread/91e3f107cd611adf ...but here's the problem in a nutshell:

Since my application's access control logic is all implemented in PHP rather than in the database (i.e., I can't add access control to my queries as a simple WHERE clause), I'm looking for a way to hook into the query process just after the records have been hydrated and actually modify the result set that gets returned, such that only permissible records show up in the final result set.

Unfortunately, although there are several listener methods that look promising for this, none of them seem to have access to the data being returned. For instance, if I run a custom query via Doctrine_Query::execute(), the postQuery() hook definitely runs ...but it doesn't give me access to anything but the query string itself.

Since, in some instances (e.g., hydration listeners), the Doctrine_Event object is assigned arbitrary data that the listener can modify, I'm wondering if the same thing couldn't be done more universally?



 Comments   
Comment by Jonathan H. Wage [ 24/Nov/09 ]

In Doctrine 1.2 you can create custom hydrators. You can extend the core hydrators to remove the data you want? I think that would work.

Comment by Adam Jensen [ 24/Nov/09 ]

Sure enough, that does the trick!

There are a couple of downsides, though, that might be worth considering in terms of future development:

1. It would be nice to be able to specify constructor arguments for the hydrator, so that collaborators can be injected. In my example, the hydrator needs access to the application's access control list object; currently it's simply retrieving it from a global registry, but it would be nice for testing's sake to be able to inject it instead.
2. It would also be nice to be able to chain multiple hydrators together; that's one reason I was looking at listeners, since they've got that capability already. That approach allows you to keep distinct behavior distinct a lot more easily.

Ultimately, I'd still kind of like to see another listener method available ...say, preHydrateResultSet() and postHydrateResultSet()? I think that would be a more flexible approach, even though the custom hydrator solution works quite well.

Thanks!
Adam

Comment by Jonathan H. Wage [ 24/Nov/09 ]

I like the idea. I'll move this to 1.3. I don't think we're gonna have a 1.3 version but if we do, it'll be there.

Comment by Jonathan H. Wage [ 15/Mar/10 ]

We can include this in a 1.2.x release if you would like to provide a patch and some tests. Thanks, Jon





[DC-373] Relating to Translation table (generated by Doctrine_I18n) doesn't work correctly after resetting connection Created: 20/Dec/09  Updated: 19/Dec/14

Status: Open
Project: Doctrine 1
Component/s: Connection, I18n
Affects Version/s: 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Kousuke Ebihara Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 2
Labels: None
Environment:

PHP 5.2.11 (with Suhosin-Patch 0.9.7)
PHP 5.3.6


Attachments: File DC373TestCase.php    

 Description   

Relating to Translation table (generated by Doctrine_I18n) doesn't work correctly after resetting connection.

First, I defined the following schema.yml::

 
  Example:
    actAs:
      I18n:
        fields: [title]
    columns:
        title: string(128)

Next, I prepared the following fixture file::

 
  Example:
    Example_1:
      Translation:
        en:
          title: "Title"
        ja:
          title: "題名"

Next, I run "build-all-reload" task. The table was created and data was loaded.

And I write the following code::

 
  Doctrine_Core::loadModels('models');
  $example = Doctrine_Core::getTable('Example')->find(1);
  
  var_dump(
    $example->Translation['en']->title,
    $example->Translation['ja']->title
  );
  
  Doctrine_Manager::resetInstance();
  Doctrine_Manager::getInstance()->openConnection(DSN, 'doctrine');
  
  $example2 = Doctrine_Core::getTable('Example')->find(1);
  var_dump(
    $example2->Translation['en']->title,
    $example2->Translation['ja']->title
  );

I try executing my code, but I got the following error::

  string(5) "Title"
  string(6) "題名"
  
  Doctrine_Connection_Mysql_Exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.title' in 'field list' in /path/to/doctrine/Doctrine/Connection.php on line 1082
  
  Call Stack:
      0.0055      65352   1. {main}() /path/to/my/code/test.php:0
      0.2776    5873388   2. Doctrine_Table->find() /path/to/my/code/test.php:52
      0.2793    5881152   3. Doctrine_Query->fetchOne() /path/to/doctrine/Doctrine/Table.php:1611
      0.2793    5881296   4. Doctrine_Query_Abstract->execute() /path/to/doctrine/Doctrine/Query.php:281
      0.2793    5881892   5. Doctrine_Query_Abstract->_execute() /path/to/doctrine/Doctrine/Query/Abstract.php:1026
      0.3127    5890712   6. Doctrine_Connection->execute() /path/to/doctrine/Doctrine/Query/Abstract.php:976
      0.3164    5892632   7. Doctrine_Connection_Statement->execute() /path/to/doctrine/Doctrine/Connection.php:1006
      0.3181    5907408   8. Doctrine_Connection->rethrowException() /path/to/doctrine/Doctrine/Connection/Statement.php:269


 Comments   
Comment by Arnaud Charlier [ 02/Nov/10 ]

Good Morning,

First, thanks a lot for your work on Doctrine. It's a real great tool we love to use.

Currently in one of our big application we have exactly the same issue.
It seems when we close the connection, the reference with the objectTranslation is lost.
Re-open the connection seems not able to reinstantiate this Translation link to the objectTranslation.

Currently we have no solution, but we are still investigating this.

I'm available to go deep in the code with you, but any Doctrine Team help will be really nice.

Thanks to let me know as soon as possible.

Arnaud

Comment by Joe Siponen [ 27/May/11 ]

I've just now battled with the very same problem in Doctrine 1.2 (the version bundled with symfony 1.4) and the problem seems to be caused by the fact that Doctrine_Record_Generator simply isn't written such that it is able to reinitialize generators for unloaded table instances after a connection is closed. This problem also manifests itself after a table has been loaded in a connection and one tries retrieve a table again after Doctrine_Connection->evictTables() has been called. This makes it impossible to to open more than one connection at a time in a request/script when using behaviors that dynamically modify table instances (such as the i18n behavior).

Doctrine_Record_Generator determines if it needs to run its initialization methods simply by checking if the to-be generated class, as defined by the className option, exists using a class_exists call. This means that the first time this method is called the initialization happens but for every subsequent call no initialization is made. Now, in the i18m behavior, the important initialization happens in its setTableDefinition method in which it removes any of the translated fields from the table instance that is been setup and redefines them as relations on the to-be-created Translation class. It then finishes off by dynamically declaring the new class for the translation record using its generateClassFromTable method.

Thus, the first time everything goes smoothly and the i18n generator's setTableDefinition is called and the table instance is properly initialized. Everything will now work as expected while the current connection is open since the connection instance keeps the i18n modified table instances alive and well for callers.

But, when the current connection is closed the i18n modified table instances it holds are also removed (goes out of scope). Then, when a new connection is opened, this new connection will start without having any table instances. This means that the next time one asks the new connection for a table instance of the same class with the i18n behavior the i18n behaviors will fail to initialize because the generator at this time believes its class has actually been initialized which, in turn, means that the table using the i18n behavior isn't properly initialized. No initialization means that this table will now include the non-existant i18n fields in the select part of its queries (those are in the translation table) causing those queries to fail miserably.

I believe this could be fixed by adding a static attribute to Doctrine_Record_Generator that tracks the spl_object_hash of the underlying dbh instance variable of the doctrine connection of the table parameter. If the hash is the same the next time that the initialize method is called the generator can decide not to reinitialize itself but if it detects that the hash of the current connection is different then that is definitely a clue to the generator that it needs to reinitialize itself (i.e. run all of the initialization methods but generateClassFromTable which should't be called more than once).

Maybe do it like this perhaps:

 
abstract class Doctrine_Record_Generator extends Doctrine_Record_Abstract
{
  public function initialize(Doctrine_Table $table)
  {
    /* ... */ 
  
    $currentConnectionHash = spl_object_hash($table->getConnection()->getDbh());
    
    //Next part is called if this is the first connection made or if this is a new open connection with new table instances
    if ($currentConnectionHash != self::$lastConnectionHash)
    {
      self::$lastConnectionHash = $currentConnectionHash;
      
      $this->buildTable();

      $fk = $this->buildForeignKeys($this->_options['table']);

      $this->_table->setColumns($fk);

      $this->buildRelation();

      $this->setTableDefinition();
      $this->setUp();
      
      if ($this->_options['generateFiles'] === false && class_exists($this->_options['className'])) {
        $this->generateClassFromTable($this->_table); //Don't generate the class more than once ever
      }
      
      $this->buildChildDefinitions();

      $this->_table->initIdentifier();
    }
  }
}
Comment by Joe Siponen [ 16/Jun/11 ]

Failing test case attached

Comment by Kousuke Ebihara [ 08/Jun/12 ]

Good job, Joe Siponen! Thanks for your nice patch!

I can't understand why the Doctrine team discontinued maintenance of Doctrine 1 without any fixes for some serious issues like this problem...

Joe, would you send your patch by pull-request in GitHub? They might notice this problem and try to fix in official repository by your request. If you cannnot, I will do it as your proxy. (Of course I'm going to describe your credit)

Comment by Kousuke Ebihara [ 11/Sep/12 ]

I've tested Joe Siponen's patch, it would be good in a situation of single connection, but it doesn't work in multiple connections.

So I modified your patch to fit my needs. I'm testing my arranged patch and I want to publish it ASAP...

Comment by Baptiste SIMON - Libre Informatique [ 15/Dec/14 ]

Hi guys,

I found a workaround for this bug on multiple DB connections :
In my *-schema.yml I have defined my i18n table as :

(...)
actAs:
I18n:
fields: [xxx, yyy, zzz]
generateFiles: true
generatePath: <?php echo sfConfig::get('sf_lib_dir'); ?>/model/doctrine/i18n
(...)

(notice the generateFiles & generatePath...)

This (alone) seems to solve my issue. I'll give more feed back if there is any.
FEEDBACK: do not work with inheritated behaviors... so it's not correct for our needs.

sources: http://forum.symfony-project.org/viewtopic.php?t=24071

Comment by Baptiste SIMON - Libre Informatique [ 15/Dec/14 ]

eventually, for a portable solution (web), you can use this path :

(...)
generatePath: ../<?php echo str_replace(sfConfig::get('sf_root_dir').'/', '', sfConfig::get('sf_lib_dir')) ?>/model/doctrine/i18n
(...)

this is a trick for file replication between servers that have different DOCUMENT_ROOT path.

Comment by Baptiste SIMON - Libre Informatique [ 19/Dec/14 ]

ok sorry for the multiple posts... I maybe have found a smart solution by patching Doctrine/Record/Generator.php that way :

Index: Doctrine/Record/Generator.php
===================================================================
— Doctrine/Record/Generator.php (révision 4690)
+++ Doctrine/Record/Generator.php (copie de travail)
@@ -163,7 +163,7 @@
// check that class doesn't exist (otherwise we cannot create it)
if ($this->_options['generateFiles'] === false && class_exists($this->_options['className']))

{ $this->_table = Doctrine_Core::getTable($this->_options['className']); - return false; + //return false; }

$this->buildTable();
@@ -461,10 +461,10 @@
} else

{ throw new Doctrine_Record_Exception('If you wish to generate files then you must specify the path to generate the files in.'); }
  • } else { + }

    elseif ( !class_exists($definition['className']) )

    { $def = $builder->buildDefinition($definition); eval($def); }

    }

This implicates multiple rebuilding of the same class, but at least, it works... without any modifications in the schema.

Comment by Baptiste SIMON - Libre Informatique [ 19/Dec/14 ]

I found another failing case, very very isolated... And I improved the patch.
To avoid some kind of flooding here, here is the reference of the latest solution :

http://www.e-glop.net/main/Rendre_Doctrine1_multi-connexions_fonctionnel_avec_ses_diff%C3%A9rents_Behaviors





[DC-975] Treat sql server error 2601 as Doctrine_Core::ERR_ALREADY_EXISTS Created: 17/Feb/11  Updated: 17/Feb/11

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Ben Davies Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Sql server


Attachments: Text File Doctrine_Connection_Mssql_Exception.patch    

 Description   

Patch attached to treat sql server error 2601 (Integrity constraint violation) as Doctrine_Core::ERR_ALREADY_EXISTS






[DC-894] Typo in Doctrine_Manager::getConnectionDrivers() Created: 19/Oct/10  Updated: 19/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Akitaka Kohno Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

symfony 1.4 / PHP 5.2.13 / CentOS5.4



 Description   

Hello.

getConnectionDrivers is returning member variable '_connectionsDrivers' at line 809.
It's probably typo, I think this variable name should be '_connectionDrivers'.






[DC-879] MSSQL - missing function date_part() in Expression/Mssql.php [+patch] Created: 05/Oct/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2, 1.2.3
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Missing function date_part() in Expression/Mssql.php. I don't know why the set of expressions is different for each driver. This makes it hard to develop database independent.






[DC-861] Make sure doctrine uses the right connection when creating a query from a table object Created: 08/Sep/10  Updated: 08/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Emmanuel Delescolle Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All



 Description   

Line# 1036
When using Table::createQuery, null is specified as the connection when calling Doctrine_Query::create() which results in using the default connection while the "correct" connection can be know ($this->getConnection())

here is the fix:

— a/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Table.php
+++ b/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Table.php
@@ -1033,7 +1033,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable

$class = $this->getAttribute(Doctrine_Core::ATTR_QUERY_CLASS);

  • return Doctrine_Query::create(null, $class)
    + return Doctrine_Query::create($this->getConnection(), $class)
    >from($this>getComponentName() . $alias);
    }





[DC-843] MSSQL - Equal-to Operator doesn't work with columns of type text in where condition [+patch] Created: 26/Aug/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Example:

Doctrine::getTable('Ticket_DCXXX2_Model')->findByUsernameAndFoo('foo', 'bar');

foo is of type "text". Doctrine generates "where .... foo = 'bar'", but this will throw an mssql exception because you cant use the equal to operator in mssql for text and varchar types. Doctrine should consider this database related behavoir, shouldn't it?



 Comments   
Comment by Enrico Stahn [ 26/Aug/10 ]

TestCase added http://github.com/estahn/doctrine1/compare/master...DC-843

Comment by Enrico Stahn [ 27/Aug/10 ]

Patch added to github (see above)

commit msg: DC-843 fix (TestCase need fix for DC-841 to run successfully)

Comment by Enrico Stahn [ 02/Sep/10 ]

I made a mistake with github, the updated branch can be found at
http://github.com/estahn/doctrine1/tree/DC-843-2





[DC-808] Doctrine_Connection_Statement->execute() Do not pass failing query to Doctrine_Connection->rethrowException() Created: 05/Aug/10  Updated: 05/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Alexandre Ravey Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File Doctrine_Connection_Statement.patch    

 Description   

When Doctrine_Connection_Statement->execute() fail on a query, Exception is rethrown by Doctrine_Connection.

But the failing query is not passed to rethrowException() as third parameter, which make debug very difficult.

See attached patch file to correct this.






[DC-840] MSSQL - strange behavior with multiple addWhere conditions and ">" [+patch] Created: 25/Aug/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In the first example below the second parameter wasn't replaced by the given value. I tracked it down and i suppose it's because of the ">" sign. It's the same for "<". Equal-Operator (=) works fine.

        $q = Doctrine_Query::create()
            ->select('password, modified_at')
            ->from('Ticket_DCXXX_Model')
            ->andWhere('password = ?', 'abc')
            ->andWhere('modified_at > ?', '2010-01-01')
SELECT [t].[id] AS [t__id], [t].[password] AS [t__password], [t].[modified_at] AS [t__modified_at]
FROM [ticket__d_c_x_x_x__model] [t]
WHERE ([t].[password] =  'abc' AND [t].[modified_at] > ?)
        $q = Doctrine_Query::create()
            ->select('password, modified_at')
            ->from('Ticket_DCXXX_Model')
            ->andWhere('modified_at > ?', '2010-01-01')
            ->andWhere('password = ?', 'abc')
SELECT [t].[id] AS [t__id], [t].[password] AS [t__password], [t].[modified_at] AS [t__modified_at]
FROM [ticket__d_c_x_x_x__model] [t]
WHERE ([t].[modified_at] >  '2010-01-01' AND [t].[password] =  'abc')


 Comments   
Comment by Enrico Stahn [ 25/Aug/10 ]

http://github.com/estahn/doctrine1/compare/master...DC-840

Comment by Enrico Stahn [ 27/Aug/10 ]

see DC-841





[DC-743] Incompatibilty between fixture import and accessors extends Created: 16/Jun/10  Updated: 22/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures, Import/Export
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Brice Favre Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 2
Labels: None
Environment:

Window, PHP5, Symfony



 Description   

Hello,

I had a problem when i try to import data with an extended accessors when i try to insert a content with a relation. I discovered this problem in symfony.

For example, here is my table :

 
News:
  tableName: ne_news
  columns:
    id:           { type: integer(4), primary: true, autoincrement: true }
    author_id:    { type: integer(4), notnull: true }
    name:         { type: string(255) }
    description:  { type: text }
  relations:
    author: { class: sfGuardUser, onDelete: NULL, local: author_id, foreign: id, foreignAlias: sfGuardUser }

And the fixture :

 
SfGuardUser:
  sadmin:
    username:       admin
    password:       admin
    is_super_admin: true
  author1:
    username: myname
    
News:
  News1:
    name: Test 1
    description: Description of news 1
    author: author1

I import it with symfony doctrine:data-load and it works.

If i add a news.class.php and extends the autogenerated class it fails.

 
    public function setAuthor($v)
    {
        //__log('extending setter');
        return $this->_set('author', $v);
    }

WhenDoctrine_Data_Import finds the setAuthor function, it wont transform author1 in object so $v will be a string, not an sfGuardUser object.

What do you think? Is a common behavior, how can i extends my accessor?



 Comments   
Comment by ryan [ 22/Jul/11 ]

this is the same issue as DC-735





[DC-983] Fixtures loading is repeated for each database connections Created: 08/Mar/11  Updated: 08/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Ludovic Vigouroux Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Bug found when working on project ma-residence.fr. Data loading was repeated twice, and in the second run, empty rows were inserted in database, resulting in major headache in development team.

A same flush tree is built for each connections. It results in multiple loops of data load when there is more than one connection.



 Comments   
Comment by Ludovic Vigouroux [ 08/Mar/11 ]

A proposition to fix it is on github https://github.com/ludovig/doctrine1





[DC-940] Doctrine - loading a YAML fixture with French characters, replaces the accents with junk Created: 26/Nov/10  Updated: 26/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Ramin Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MAC OS X (10.6.5)
MAMP 1.9.4
PHP 5.3.2



 Description   

Hi,

My Doctrine 1.2 is integrated inside CodeIgniter as a hook and I know that my char-set is utf8 with collation utf8_unicode_ci.

I have two YAML files, one for creating the DB and its tables and one to load some test data. My data can contain French accents (çéïë...). In my schama.yml I have correctly specified the collation and char-set:

options:
type: INNODB
charset: utf8
collate: utf8_unicode_ci

I double checked the settings in phpMyAdmin, everything is correct.

When I run my doctrine script from commandline to load my fixture to populate one of tables, all the French accents are replaced by junk!

Am I missing a setting or configuration or is there a bug in Doctrine?

I appreciate any help. Cheers.

P.S. Everything else works like a charm






[DC-938] Impossible to use other formats than YAML in data import Created: 25/Nov/10  Updated: 25/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Mael Nison Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

File Doctrine/Data/Import.php, line #80
if (end($e) == 'yml')

So, if the file is a .json (for exemple), it will be impossible to load it, even if we have specified "json" as format parameter.
And it sucks.

The fix would just be to change the line to :
if (end($e) == $this->getFormat())






[DC-831] Importing fixtures fails when GoogleI18n used with "Couldn't create collection index. Record field 'lang' was null." Created: 17/Aug/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures, I18n, Import/Export
Affects Version/s: 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jakub Argasiński Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Mac OS X 10.6.4, Zend Server CE 5.0.2 (irrelevant, I guess)


Attachments: Text File fix_google18n_and_similiar_import_problem.patch    

 Description   

There's a problem with Doctrine_Data_Import. When trying to load a fixture record with translations, and GoogleI18n (or similar) instead of I18n is used (via actAs()), the following crash happens:
Couldn't create collection index. Record field 'lang' was null.

#0 /Users/argasek/Sites/fwm/library/doctrine/Doctrine/Access.php(131): Doctrine_Collection->add(Object(Fwm_Shop_Catalog_CategoryTranslation))
#1 /Users/argasek/Sites/test/library/doctrine/Doctrine/Data/Import.php(241): Doctrine_Access->offsetSet(NULL, Object(Test_Shop_Catalog_CategoryTranslation))
#2 /Users/argasek/Sites/test/library/doctrine/Doctrine/Data/Import.php(335): Doctrine_Data_Import->_processRow('(catalog_catego...', Array)
#3 /Users/argasek/Sites/test/library/doctrine/Doctrine/Data/Import.php(118): Doctrine_Data_Import->_loadData(Array)
#4 /Users/argasek/Sites/test/library/doctrine/Doctrine/Data.php(222): Doctrine_Data_Import->doImport(false)
#5 /Users/argasek/Sites/test/library/doctrine/Doctrine/Core.php(1011): Doctrine_Data->importData('/Users/argasek/...', 'yml', Array, false)
#6 /Users/argasek/Sites/test/library/doctrine/Doctrine/Task/LoadData.php(43): Doctrine_Core::loadData('/Users/argasek/...', false)
#7 /Users/argasek/Sites/test/library/doctrine/Doctrine/Cli.php(516): Doctrine_Task_LoadData->execute()
#8 /Users/argasek/Sites/test/library/doctrine/Doctrine/Cli.php(498): Doctrine_Cli->executeTask(Object(Doctrine_Task_LoadData), Array)
#9 /Users/argasek/Sites/test/library/doctrine/Doctrine/Cli.php(452): Doctrine_Cli->_run(Array)
#10 /Users/argasek/Sites/test/scripts/doctrine-cli.php(29): Doctrine_Cli->run(Array)
#11

{main}

I have narrowed down the problem to the line 135 of Doctrine/Data/Import.php, ie.

if ($table->hasRelation($key) && is_array($value) && ! $table->hasTemplate('Doctrine_Template_I18n')) {

In case of GoogleI18n, $table->hasTemplate('Doctrine_Template_I18n') returns false.

I have no idea how to patch this in a sane way. Adding another condition (&& ! $table->hasTemplate('Doctrine_Template_GoogleI18n') serves well as a workaround, but such condition would be required for any class similar to Doctrine_Template_GoogleI18n. I guess the condition should check if it's a Doctrine_Template_I18n template or any template iherited from this class?...



 Comments   
Comment by Jakub Argasiński [ 17/Aug/10 ]

I have provided a quick workaround patch for this problem, with an approach described in my report, ie. checking whether table has a template being an instance of or a child of Doctrine_Template_I18n.





[DC-322] Data dump fails on tables with quoted identifiers Created: 03/Dec/09  Updated: 04/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Massimiliano Torromeo Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

linux, apache 2, mysql 5.1, php 5.2



 Description   

While dumping a table with a quoted identifier `numeric`, doctrine failed because the constructed query had an invalid alias the field: c__`numeric`.

Output:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '`numeric`, c.alpha3 AS c_alpha3, c.alpha2 AS calpha2 FROM country_codes c' at line 1. Failing Query: "SELECT c.country AS ccountry, c.`numeric` AS c`numeric`, c.alpha3 AS calpha3, c.alpha2 AS c_alpha2 FROM country_codes c"

I know that using quoted identifiers is discouraged but I think this could be easily solvable.

Thanks.



 Comments   
Comment by Juozas Kaziukenas [ 03/Dec/09 ]

In which code part are you quoting that column? Because just enabling identifiers quoting would result in completely different results (at least there will be all columns quotes or none).

Comment by Massimiliano Torromeo [ 04/Dec/09 ]

I'm not using Doctrine::ATTR_QUOTE_IDENTIFIER, I generated a yaml from a preexisting db and then adapted it.

It generated the following definition:
CountryCodes:
columns:
country:
type: string(32)
notnull: true
`numeric`:
type: integer(2)
unsigned: 1
primary: true
alpha3:
type: string(3)
fixed: true
notnull: true
alpha2:
type: string(2)
fixed: true
notnull: true

but it was with an old version of Doctrine and this is not the case anymore (I tried regenerating it). I assumed it was correct to quote one single identifier, but I now guess it wasn't.

I think this can be closed as NotBug.

Sorry for the trouble.
Regards.

Comment by Juozas Kaziukenas [ 04/Dec/09 ]

However, variables cannot be quoted like that - quoting happens after actual columns are constructed, so now Doctrine needs to unquote it and do it's stuff. If you want quoting - enable that option and it will do it for you, or the best - don't use reserved words in your schema

This issue can be closed as Invalid.





[DC-1029] Extensions of Doctrine_Template_I18n incompatible with Doctrine_Import Created: 18/Aug/11  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Data Fixtures, I18n, Import/Export
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: Pierrot Evrard Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7, XAMPP 1.7.4 with APC and Curl, symfony 1.4.8


Attachments: Text File DC-1029.patch    

 Description   

Extending Doctrine_Template_I18n class make Doctrine_Import on YAML data with translation fails...

Why ? Just because of this line :

Doctrine_Import.php, line 135 :
if ($table->hasRelation($key) && is_array($value) && ! $table->hasTemplate('Doctrine_Template_I18n')) {

In fact, having a template named "Doctrine_Template_I18n" is not strong enough to be sure that the current object has an I18n behavior.

The bug is very simple to reproduce :

1. Get a classic I18n fixtures like :

Article:
Translation:
en:
title: Lorem Ipsum

2. Then make a simple extension of the I18n template (do not do anything else but extends the Doctrine_Template_I18n class) :

class My_Doctrine_Template_I18n extends Doctrine_Template_I18n {}

3. Load the extension, assign it to your model and try to import your fixtures again. It will not work anymore.

Thanks



 Comments   
Comment by Pierrot Evrard [ 18/Aug/11 ]

See this patch where to check if the table has the I18n plugin, I check if one of the templates has a getI18n() method.

This is probably not strong enough but it can do the job until you find a better solution.

Thanks

Comment by Pierrot Evrard [ 18/Aug/11 ]

Another possibility to check that templates are I18n template, will be to create an Doctrine_I18n_Interface. Also, every template that include this interface can be considered as I18n templates.

What do you think about that ?

NB: May the interface can define the method getI18n() to be declared...





[DC-862] INNER JOIN example is same as previous LEFT JOIN example Created: 08/Sep/10  Updated: 08/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Roberto Mansfield Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

http://www.doctrine-project.org/projects/orm/1.2/docs/manual/dql-doctrine-query-language/en#join-syntax



 Description   

I was reading the "JOIN syntax" section of the documentation. The docs first talk about how the default join type is LEFT JOIN and an example is presented. Next, INNER JOINS are discussed, but the example is the same left join example used previously. Am I misunderstanding the flow of the document?






[DC-736] [Documentation] Taking Advantage of Column Aggregation Inheritance Created: 14/Jun/10  Updated: 14/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jason Brumwell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The documentation at http://www.doctrine-project.org/projects/orm/1.2/docs/cookbook/taking-advantage-of-column-aggregation-inheritance/en#taking-advantage-of-column-aggregation-inheritance states when using foreign keys with column aggregation to set:

$this->options('export','tables');

this didn't work for me after looking into it I see it should be attributes so in the base class you can write:

$this->setAttribute(Doctrine_Core::ATTR_EXPORT, Doctrine_Core::EXPORT_TABLES);

or via schema:

attributes:
export: tables






[DC-631] Documentation Created: 15/Apr/10  Updated: 15/Apr/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Task Priority: Major
Reporter: Thomas Tourlourat - Armetiz Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

http://www.doctrine-project.org/Doctrine_Record/1_2#method_importfrom

The description of the $type parameter is : Format type: xml, yml, json
But it could take an array.

So the documentation have to be update for this point.






[DC-501] Join and WITH keywords : documentation is confusing Created: 15/Feb/10  Updated: 15/Feb/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.1.6
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Julien B. Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Your documentation makes no sense to me on the usage of the WITH keyword

http://www.doctrine-project.org/documentation/manual/1_1/en/dql-doctrine-query-language:join-syntax#with-keyword

$q = Doctrine_Query::create()
  ->select('u.id, p.id')
  ->from('User u')
  ->leftJoin('u.Phonenumbers p WITH u.id = 2');

Get Users and the phone numbers if any of the user 2 (we could indeed need that kind of query)

-----------------------------------------------------------------------------------------------------------------------------------
I guess this kind of example query is better

// Documentation
Get users and their mobile phone numbers if any

$q = Doctrine_Query::create()
  ->select('u.id, p.id')
  ->from('User u')
  ->leftJoin('u.Phonenumbers p WITH p.type = ?', 'mobile');

you can expect this SQL

SELECT 
u.id AS u__id, 
p.id AS p__id 
FROM User u 
LEFT JOIN Phonenumbers p ON u.id = p.user_id AND p.type = 'mobile'

// Still in the documentation
Be aware that this query is different of

$q = Doctrine_Query::create()
  ->select('u.id, p.id')
  ->from('User u')
  ->leftJoin('u.Phonenumbers p')
  ->where('p.type = ?', 'mobile')
;

because you will strip away the users who do not have a mobile phone number

-----------------
Also the second example is more confusing ...

$q = Doctrine_Query::create()
    ->select('u.id')
    ->from('User u')
    ->leftJoin('u.Groups g')
    ->innerJoin('u.Phonenumbers p WITH u.id > 3')
    ->leftJoin('u.Email e');

Means : Get Users (who HAVE Phonenumbers (innerJoin)) with their potential (leftJoin) Groups, potential (leftJoin) Emails, and their Phonenumbers
but not for the Users 1, 2 and 3

Not really the straight forward example we can expect in a documentation

Best regards






[DC-379] No description of ATTR_DEFAULT_IDENTIFIER_OPTIONS now in "Chapter 4 Configuration" Created: 23/Dec/09  Updated: 23/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: zerkms Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In the previous (1.1) documentation version there were small but useful description about how to set up primary key (http://www.doctrine-project.org/documentation/manual/1_1/en/configuration#defaults-attributes:default-added-auto-id)
Now there is nothing about ATTR_DEFAULT_IDENTIFIER_OPTIONS and it takes about 20 minutes to debug and find out where did "id" field added

ps: message "If you find a problem with the documentation or have a suggestion, please register and open a ticket. " in the bottom of the docs pages is ambiguous due to it points to trac :-$






[DC-348] Doctrine manual does not document that columns can be added with simple inheritance, or the semantics of accessing those columns in the parent Created: 10/Dec/09  Updated: 10/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Tom Boutell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The Doctrine manual's section on inheritance mentions simple inheritance only briefly. The examples do not show that columns can be added, nor do they explain that the parent model class can also access those columns (very useful when you override its methods at the application level in Symfony).

Both behaviors are supported (Jon suggested I take advantage of them at one point) but it's easy to miss the fact that they are available. For a long time I assumed column aggregation inheritance was the only way to add columns.

I'm now exploiting simple inheritance as a way to add columns to sfGuardUser rather than introducing an sfGuardUserProfile class with all of the attendant problems of trying to pretend two tables are actually one table. This is very useful.

(Out of curiosity, is there an alternative way to add columns to plugin schemas at the app level in Symfony 1.3 similar to the way it's now done for Propel?)






[DC-339] Documentation unclear about linking inherited objects Created: 08/Dec/09  Updated: 08/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Tarjei Huse Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The (very nice) doctrine documentation fails to mention anything about how inherited objects handle relations.

I.e. if I got the model:
Entity:
columns:
username: string(20)
password: string(16)
created_at: timestamp
updated_at: timestamp

User:
inheritance:
extends: Entity
type: column_aggregation
keyField: type
keyValue: 1

Group:
inheritance:
extends: Entity
type: column_aggregation
keyField: type
keyValue: 2

Topic:
content: string
entity_id: integer
relations:
User:
class: Entity
local: entity_id
foreign: id

Can I then define both users and groups to link to Topic?






[DC-1012] Doctrine_core specified twice in documentation Defining Models -> Join Table Associations Created: 28/Jun/11  Updated: 28/Jun/11

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Documentation Priority: Minor
Reporter: Justinas Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

$manager->setAttribute(Doctrine_Core::Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true);

should be:

$manager->setAttribute(Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true);

http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models/en#relationships:join-table-associations






[DC-995] Doctrine deprecated in favor of Doctrine_Core - phpdoc Created: 06/Apr/11  Updated: 06/Apr/11

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Documentation Priority: Minor
Reporter: Pablo Grass Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

all environments



 Description   

http://www.doctrine-project.org/projects/orm/1.2/docs/whats-new/en clearly states that the Doctrine class is deprecated - e.g. in order to allow for proper autoloading.
To enable IDEs to perform proper autocomplete and to encourage programmers not to use the Doctrine class anymore, it's phpdoc block shuld by changed in order to contain a

@deprecated In favor of Doctrine_Core - this class extends Doctrine_Core for BC






[DC-923] Documentation 1.2 #working-with-models error Created: 10/Nov/10  Updated: 10/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Martin Babic Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 10.4, LAMP



 Description   

In documentation

http://www.doctrine-project.org/projects/orm/1.2/docs/manual/working-with-models/en#many-to-many-relations:creating-a-new-link

There's an error in example code:

// test.php

// ...
$user = new User();
$user->username = 'Some User';
$user->Groups[0]->username = 'Some Group';
$user->Groups[1]->username = 'Some Other Group';
$user->save();

The error is on lines:

$user->Groups[0]->username = 
$user->Groups[1]->username = 

they shoud be:

$user->Groups[0]->name = 
$user->Groups[1]->name = 

as there's no username column in schema.yml definition of Group object.






[DC-872] 1.2 Documentation on Aggregate Functions Error Created: 21/Sep/10  Updated: 21/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Isaac Foster Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In the documentation for using aggregate values with Doctrine Query (link below), there is a code snippet that shows how to access the value of the aggregate field, which does not work.

The code snippet is:

//firstsnippet after header
$q = Doctrine_Query::create()
->select('u.id, COUNT(t.id) AS num_threads')
->from('User u, u.Threads t')
->where('u.id = ?', 1)
->groupBy('u.id');

//second snippet after header
$users = $q->execute();

//fourth snippet after header
echo $users->num_threads . ' threads found';

The code from the last snippet for accessing the count value, $users->num_threads, doesn't seem to work. What does work for me is:

//access count value
echo $users[0]->num_threads

//My exact code is:
$query = Doctrine_Query::create()
->select('COUNT as batchCount')
->from('Batch');
$result = $query->execute();

echo $result->batchCount; //10
echo $result[0]->batchCount; //3 (3 is correct, from direct MySQL command line query)

It's certainly possible I'm doing something wrong, or that there is a Doctrine_Core attribute I need to set. If there is a Doctrine_Core attribute to set to automatically access aggregate values from the Collection, it would be worth noting at the top of the section.

Thanks, and thanks for Doctrine (so awesome).

Link:
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/dql-doctrine-query-language/hu#select-queries:aggregate-values






[DC-868] [Documentation] Column aggregation Created: 16/Sep/10  Updated: 16/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Michael Simpson Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The example in the documentation at http://www.doctrine-project.org/documentation/manual/1_2/en/inheritance:column-aggregation suggests that the discriminator (in this case 'type') column does not need to be defined in the parent class 'Entity'.

This did not work for me, I had to declare the discriminator column as shown in the 'Taking advantage of column aggregation inheritance' chapter at http://www.doctrine-project.org/projects/orm/1.2/docs/cookbook/taking-advantage-of-column-aggregation-inheritance/en.






[DC-846] Provide documentation for connection options Created: 29/Aug/10  Updated: 29/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Ritty Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All



 Description   

Provide additional information on connection options.

$conn = Doctrine_Manager::connection('mysql://username:password@localhost/test', 'connection 1');

just skims the surface. At least link to PDO docs. Also, what is the second parameter? I can look in API docs, but it would be helpful to have in the reference guide.

Are there any other ways to make a connection, such as through an array of parameters?






[DC-738] Missing reference to make code usable Created: 15/Jun/10  Updated: 17/Jun/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Dennis Gearon Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Doctrine web site



 Description   

Web page documentation is missing some details on following page: // ...
http://www.doctrine-project.org/documentation/manual/1_0/pl/connections:get-connection-name
http://www.doctrine-project.org/documentation/manual/1_2/pl/connections:get-connection-name

I think they were just taken out of context from a page like:
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/connections/en#get-connection-name
where a previous reference to manager .... oops, that page has no previous reference to '$manager' either!!!

Where does the $manager variable come into this? FWIW, I tried that code to get the connection name in a Symfony/Doctrine CLI Task, and it says, 'using object accessor on non object'. I'll keep working on what it's supposed to look like, but the last page above, and every page of documentation derived from it should be checked for the relevance and accuracy of the $manager variable.






[DC-1039] Return value of function Doctrine_Tree_NestedSet::fetchRoot($id) Created: 31/Oct/11  Updated: 31/Oct/11

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Documentation Priority: Trivial
Reporter: Dmitry Artanov Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In api documentation about Doctrine_Tree_NestedSet::fetchRoot($id) said - it return void. But this is not true. This function return mixed - bool or model data.






[DC-906] Missing retrieval method Created: 30/Oct/10  Updated: 31/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: Christopher W. Allen-Poole Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

online



 Description   

This page:
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/getting-started/en#getting-started

only lists svn as a way to check out the doctrine source. It's also available via git.






[DC-909] Add Some Info to Doctrine Query order by Method Documentation Created: 01/Nov/10  Updated: 01/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: Isaac Foster Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

n/a



 Description   

This is very minor, but would have saved me a few minutes. On the Doctrine Query documentation page (V1 - http://www.doctrine-project.org/projects/orm/1.2/docs/manual/dql-doctrine-query-language/en#order-by-clause), it would be useful to note that multiple calls to Doctrine_Query::orderBy() do not stack, and that the later calls will over write the previous ones. I'll propose:

To sort by multiple columns, you must specify them in one call to Doctrine_Query::orderBy(). If you call orderBy a second time, the column from the first call will not be included in the resulting query.

<code>
//works as expected
//results in ORDER BY id ASC, userName DESC
$query->orderBy('id ASC, userName DESC');

//does not work as expected
//results in ORDER BY userName DESC
$query->orderBy('id ASC')
->orderBy('userName DESC');
</code>






[DC-786] phpdoc comment error Created: 14/Jul/10  Updated: 14/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Documentation
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: mike Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

n/a



 Description   

in Doctrine/Core.php on line 881

comment for method generateModelsFromYaml() is:
881: * Generate a yaml schema file from an existing directory of models

should be:
881: * Generates models from a yaml schema file






[DC-724] Blameable relations import problem Created: 09/Jun/10  Updated: 13/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Extensions, Import/Export
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Gordon Franke Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

symfony 1.4.5 with latest doctrine 1.2 branch with sfDoctrineGuardPlugin



 Description   

The import works only when i DISABLE the update relation. When i activate the update relation i get an sql error

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`clubicious`.`location`, CONSTRAINT `location_updated_by_sf_guard_user_id` FOREIGN KEY (`updated_by`) REFERENCES `sf_guard_user` (`id`))

The relation is created correct i think the problem is in the importer???

Location:
actAs:
Timestampable: ~
Sortable: ~
Blameable:
columns:
created:
length: null
updated:
length: null
relations:
created:
disabled: false
class: sfGuardUser
updated:
disabled: false
class: sfGuardUser
columns:
name:

{ type: string(255), notnull: true }

My fixtures:
sfGuardUser:
gfranke:
id: 1
first_name: Gordon
last_name: Franke
email_address: franke@clubicious.com
username: gfranke
password: startgf
Location:
location_atomic:
name: Atomic Cafe
CreatedBy: gfranke
UpdatedBy: gfranke

location_max:
name: Max & Moritz
CreatedBy: gfranke
UpdatedBy: gfranke



 Comments   
Comment by Tim Schofield [ 13/Jul/10 ]

Same Problem with Doctrine 1.2.2 and Zend Framework 1.10

Work around for me was to disable all Blameable relations in my schema.yml

Then run

./doctrine build-all-reload

So that fixtures can load

Then enable all Blameable relations in the schema.yml

and run

./doctrine generate-models-yaml

So models are generated with the correct relations

Regards

Tim





[DC-634] getPopularTags() query fails on Postgresql Created: 15/Apr/10  Updated: 15/Apr/10

Status: Open
Project: Doctrine 1
Component/s: Extensions
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: admirau Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows, Postgresql



 Description   

When I run:
Doctrine::getTable('TaggableTag')->getPopularTags();
I get: ERROR: column "i2__1" does not exist

The failing query on PostgreSql is:

SELECT t.id AS t_id, t.name AS tname, COUNT(DISTINCT i.id) AS i_0,
(COUNT(DISTINCT i.id)) AS i__1
FROM taggable_tag t
LEFT JOIN cms_model_image_taggable_tag c ON (t.id = c.tag_id)
LEFT JOIN image i ON i.id = c.id
WHERE t.id IN
(SELECT doctrine_subquery_alias.id
FROM
(SELECT DISTINCT t2.id, (COUNT(DISTINCT i2.id)) AS i2__1
FROM taggable_tag t2
LEFT JOIN cms_model_image_taggable_tag c2 ON (t2.id = c2.tag_id)
LEFT JOIN image i2 ON i2.id = c2.id
GROUP BY t2.id HAVING i2__1 > 0
ORDER BY i2__1 DESC LIMIT 10) AS doctrine_subquery_alias)
GROUP BY t.id HAVING i__1 > 0
ORDER BY i__1 DESC

Seems that this just a PostgreSql issue.
On Mysql it runs just fine.

The corrected, working query is:

SELECT t.id AS t_id, t.name AS tname, COUNT(DISTINCT i.id) AS i_0,
(COUNT(DISTINCT i.id)) AS i__1
FROM taggable_tag t
LEFT JOIN cms_model_image_taggable_tag c ON (t.id = c.tag_id)
LEFT JOIN image i ON i.id = c.id
WHERE t.id IN
(SELECT doctrine_subquery_alias.id
FROM
(SELECT DISTINCT t2.id, (COUNT(DISTINCT i2.id)) AS i2__1
FROM taggable_tag t2
LEFT JOIN cms_model_image_taggable_tag c2 ON (t2.id = c2.tag_id)
LEFT JOIN image i2 ON i2.id = c2.id
GROUP BY t2.id HAVING COUNT(DISTINCT i2.id) > 0
ORDER BY i2__1 DESC LIMIT 10) AS doctrine_subquery_alias)
GROUP BY t.id, t.name HAVING COUNT(DISTINCT i.id) > 0
ORDER BY i__1 DESC

For more details, please read the discussion here:
http://stackoverflow.com/questions/2647537/doctrine-sql-query-works-on-mysql-on-postgresql-wont






[DC-486] Taggable extension bound to inherited class also binds to all classes, which extend the base one Created: 08/Feb/10  Updated: 08/Feb/10

Status: Open
Project: Doctrine 1
Component/s: Extensions
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Alexander Panshin Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

php5.2.11, symfony 1.4, Doctrine 1.2, Taggable 1.0



 Description   

This is my schema.yml:

Tale:
actAs:
Taggable:
columns: # there are some not interesting columns

FolkTale:
inheritance:
extends: Tale
type: column_aggregation
keyField: type
keyValue: folk
columns:
folk_id: integer
relations:
Folk:
class: Folk
local: folk_id
foreign: id
type: one
onDelete: CASCADE

AuthoredTale:
inheritance:
extends: Tale
type: column_aggregation
keyField: type
keyValue: authored
columns:
author_id: integer
relations:
Author:
class: Author
local: author_id
foreign: id
type: one
onDelete: CASCADE

When I do ./symfony doctrine:build --all I see three *_taggable_tag table in my DB (folk_tale_taggable_tag, authored_tale_taggable_tag and tale_tag) instead of expected one tale_tag.






[DC-440] doctrine migration fails with taggable extension Created: 20/Jan/10  Updated: 22/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Extensions, Migrations
Affects Version/s: 1.2.0, 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Robert Gruendler Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

osx 10.6, apache 2, php 5.3, symfony 1.4



 Description   

When adding the Taggable behaviour to an entity, the doctrine migration fails (i'm using the symfony task) with the follwing error:

>> doctrine Migrating from version 0 to 1

The following errors occurred:

  • SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails. Failing Query: "DROP TABLE taggable_tag"

I have a single entity in my schema, with the Taggable behavior attached:

Article:
actAs:
Taggable: ~ 
columns:
title:

{ type: string(255), notnull: true }

body:

{ type: clob }

The Version1 class which was generate by the generate-migrations-diff task looks like this:

<?php
/**

  • This class has been auto-generated by the Doctrine ORM Framework
    */
    class Version1 extends Doctrine_Migration_Base
    {
    public function up() { $this->dropTable('taggable_tag'); }

public function down()

{ $this->createTable('taggable_tag', array( 'id' => array( 'type' => 'integer', 'length' => '8', 'autoincrement' => '1', 'primary' => '1', ), 'name' => array( 'unique' => '1', 'type' => 'string', 'length' => '255', ), ), array( 'type' => '', 'indexes' => array( ), 'primary' => array( 0 => 'id', ), 'collate' => '', 'charset' => '', )); }

}



 Comments   
Comment by Robert Gruendler [ 22/Jan/10 ]

i think i found the reason for this. The sfDoctrineGenerateMigrationsDiffTask seems to build it's diff from yml schema files:

protected function execute()....

$this->callDoctrineCli('generate-migrations-diff', array(
'yaml_schema_path' => $this->prepareSchemaFile($config['yaml_schema_path']),
));

The task does not know anything about the models in the doctrine_extensions folder, and there are no yaml files for their
schema, so symfony migration tasks won't work with extensions.

It would be great if this would be mentioned somewhere in the docs of the extensions.





[DC-438] Nesting Taggable and I18N Created: 19/Jan/10  Updated: 19/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Extensions, I18n
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Sorin Neacsu Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.2.6, MySQL 5.0.75, Symfony 1.3.1



 Description   

The Taggable extension doesnt work correctly when nested under I18N.
The page_translation_taggable_tag table appears to be correctly created, it has 3 columns: id, lang, tag_id
But when you save a tag like this
$page->Translation['en']->setTags('tag 1, tag2');
the lang column in page_translation_taggable_tag is empty
and this doesnt work either:
$page->setTags('tag 1, tag2');

Schema is this:
Page:
actAs:
I18n:
fields: [title, contents]
actAs:
Taggable: ~
columns:
title:

{type: string(255), notnull: true}

contents: clob






[DC-67] Taggable not working Created: 28/Sep/09  Updated: 15/Apr/10

Status: Reopened
Project: Doctrine 1
Component/s: Extensions
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: admirau Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 4
Labels: None
Environment:

PHP 5.2.8, Doctrine 1.2.0 Alpha1, Vista, Sandbox 1.2.0 Alpha1



 Description   

After enabling Taggable extension, magic methods on the tables (e.g. getPopularTags)
cannot be reached:

Doctrine::getTable('Upload')->getPopularTags();

Fatal error: Uncaught exception 'Doctrine_Table_Exception' with message 'Unknown method Doctrine_Table::getPopularTags' in C:\Users\user\www\extens.dev\lib\Doctrine\Table.php:2608 Stack trace: #0 [internal function]: Doctrine_Table->__call('getPopularTags', Array) #1 C:\Users\user\www\extens.dev\index.php(7): Doctrine_Table->getPopularTags() #2

{main}

thrown in C:\Users\user\www\extens.dev\lib\Doctrine\Table.php on line 2608



 Comments   
Comment by admirau [ 08/Oct/09 ]

The same with Alpha2

Comment by admirau [ 10/Oct/09 ]

Running the tests results in one failure:

Doctrine Unit Tests
===================
Doctrine_Template_Taggable_TestCase.............................................failed

Unexpected Doctrine_Connection_Sqlite_Exception thrown in [Doctrine_Template_Taggable_TestCase] with message [SQLSTATE[HY000]: General error: 1 no such column: a__2] in C:\Users\user\www\extens.dev\lib\Doctrine\Connection.php on line 1067

Trace
-------------

#0 C:\Users\user\www\extens.dev\lib\Doctrine\Connection.php(1015): Doctrine_Connection->rethrowException(Object(PDOException), Object(Doctrine_Connection_Sqlite))
#1 C:\Users\user\www\extens.dev\lib\Doctrine\Query\Abstract.php(936): Doctrine_Connection->execute('SELECT t.id AS ...', Array)
#2 C:\Users\user\www\extens.dev\lib\Doctrine\Query\Abstract.php(990): Doctrine_Query_Abstract->_execute(Array)
#3 C:\Users\user\www\extens.dev\tools\sandbox\extensions\Taggable\lib\Doctrine\Template\TaggableTag.php(76): Doctrine_Query_Abstract->execute(Array, 2)
#4 [internal function]: Doctrine_Template_TaggableTag->getPopularTagsTableProxy(Array)
#5 C:\Users\user\www\extens.dev\lib\Doctrine\Record.php(2569): call_user_func_array(Array, Array)
#6 [internal function]: Doctrine_Record->__call('getPopularTagsT...', Array)
#7 [internal function]: TaggableTag->getPopularTagsTableProxy(Array)
#8 C:\Users\user\www\extens.dev\lib\Doctrine\Table.php(2605): call_user_func_array(Array, Array)
#9 [internal function]: Doctrine_Table->__call('getPopularTags', Array)
#10 C:\Users\user\www\extens.dev\tools\sandbox\extensions\Taggable\tests\Template\TaggableTestCase.php(216): Doctrine_Table->getPopularTags(Array)
#11 C:\Users\user\www\extens.dev\tests\DoctrineTest\UnitTestCase.php(144): Doctrine_Template_Taggable_TestCase->testGetPopularTags()
#12 C:\Users\user\www\extens.dev\tests\DoctrineTest\GroupTest.php(61): UnitTestCase->run()
#13 C:\Users\user\www\extens.dev\tests\DoctrineTest.php(180): GroupTest->run(Object(DoctrineTest_Reporter_Cli), '')
#14 C:\Users\user\www\extens.dev\tools\sandbox\extensions\Taggable\tests\run.php(29): DoctrineTest->run()
#15

{main}

Tested: 1 test cases.
Successes: 26 passes.
Failures: 1 fails.
Number of new Failures: 0
Number of fixed Failures: 0

Tests ran in 1 seconds and used 15279.15625 KB of memory

Comment by Jonathan H. Wage [ 03/Nov/09 ]

The tests all pass now.

http://www.doctrine-project.org/extension/Taggable/1_2-1_0/tests

Comment by admirau [ 04/Nov/09 ]

It still does not work on my environment (Windows or Ubuntu 9.10, PHP 5.3/5.2.6)
The test result is a bit different, but still fails:

Doctrine Unit Tests
===================
Doctrine_Template_Taggable_TestCase.............................................failed

Unexpected Doctrine_Record_UnknownPropertyException thrown in [Doctrine_Template_Taggable_TestCase] with message [Unknown record property / related component "total_num" on "TaggableTag"] in /home/user/doctrine12b/lib/Doctrine/Record/Filter/Standard.php on line 55

Trace
-------------

#0 /home/taat/doctrine12b/lib/Doctrine/Record.php(1359): Doctrine_Record_Filter_Standard->filterGet(Object(TaggableTag), 'total_num')
#1 /home/taat/doctrine12b/lib/Doctrine/Record.php(1318): Doctrine_Record->_get('total_num', true)
#2 /home/taat/doctrine12b/lib/Doctrine/Access.php(117): Doctrine_Record->get('total_num')
#3 /home/taat/doctrine12b/tools/sandbox/extensions/Taggable/tests/Template/TaggableTestCase.php(217): Doctrine_Access->offsetGet('total_num')
#4 /home/taat/doctrine12b/tests/DoctrineTest/UnitTestCase.php(144): Doctrine_Template_Taggable_TestCase->testGetPopularTags()
#5 /home/taat/doctrine12b/tests/DoctrineTest/GroupTest.php(61): UnitTestCase->run()
#6 /home/taat/doctrine12b/tests/DoctrineTest.php(180): GroupTest->run(Object(DoctrineTest_Reporter_Cli), '')
#7 /home/taat/doctrine12b/tools/sandbox/extensions/Taggable/tests/run.php(29): DoctrineTest->run()
#8

{main}

Tested: 1 test cases.
Successes: 26 passes.
Failures: 1 fails.
Number of new Failures: 0
Number of fixed Failures: 0

Comment by Jonathan H. Wage [ 04/Nov/09 ]

Did you update Doctrine? I fixed something in Doctrine 1.2 that fixes it.

Comment by admirau [ 04/Nov/09 ]

Yes, the results above ("total_num") I get after updating to 1.2.0-BETA1.
At 1.2.0-ALPHA2 it was "no such column: a__2" (see above comments).

Do the extensions work with 2.0, or they are 1.2 specific?

Comment by Jonathan H. Wage [ 04/Nov/09 ]

1.2 specific. I don't get any fails now, can you try and troubleshoot it and figure out why it fails for you? They don't fail for me anywhere.

Comment by admirau [ 04/Nov/09 ]

Doctrine_Template_Taggable_TestCase::testGetPopularTags()
line 214:
$test = Doctrine::getTable('TaggableTag')->getPopularTags(array('ArticleTaggableTest', 'ArticleTaggableTest2'));

// compare this with your results
echo serialize($test);
result:
C:19:"Doctrine_Collection":169:{a:7:{s:4:"data";a:0:{}s:6:"_table";s:11:"TaggableTag";s:9:"_snapshot";a:0:{}s:14:"referenceField";N;s:9:"keyColumn";s:4:"name";s:8:"_locator";N;s:10:"_resources";a:0:{}}}

When I try to var_dump($test),
I get circular dependency.
I tried to save results of var_dump($test) to disk, by I get 1,5GB file, and still growing...

Maybe this article helps somehow:
http://www.bigroom.co.uk/blog/php-nesting-level-too-deep-recursive-dependency

Can I see the fix you mentioned above?

I'm sorry, but I do not know what else I can do.
Any ideas?

Comment by Jonathan H. Wage [ 10/Nov/09 ]

I am not sure what to say since it is working for me on all the machines I test. I'll be happy to look if I can get something to fail so I can troubleshoot it.

Comment by admirau [ 11/Nov/09 ]

I've tested on PLD Linux too.
The same thing.

Could you provide sample server/php configuration on which the tests are passing?

Can you describe the fix you've made to correct the errors with ''Unknown method Doctrine_Table::getPopularTags'.
Maybe I can manage to investigate it, but I do not know where to start.

Comment by admirau [ 11/Nov/09 ]

Sorry for reopening this again.

After upgrading to BETA2 all Taggable tests are passing OK for me too.

However, in the code I still get 'Unknown method BlogPostTable::getPopularTags' in /tools\sandbox\lib\Doctrine\Table.php:2793'
Isn't it a regression of the bug you've already fixed before ALPHA2?

Here is the description of how I came to this exception.

At the very end of config.php:

$manager->registerExtension('Taggable');

In the index.php:

<?php

require_once('config.php');

$models = Doctrine_Core::loadModels('models');

$post = new BlogPost();
$post->title = 'This is a sample blog post';
$post->description = 'Cool!';
$post->setTags('2009, symfony, doctrine');
$post->save();

$table = Doctrine::getTable('BlogPost');
echo get_class($table); // echoes Doctrine_Collection
$table->getPopularTags(); // this throws the exception

Then in the console:
php doctrine.php create-db
php doctrine.php generate-models-yaml (BaseBlogPost, BlogPost, BlogPostTable were generated)
php doctrine.php generate-sql (see SQL below)
php doctrine.php create-tables
(all ok)

php index.php

result:

BlogPostTablePHP Fatal error: Uncaught exception 'Doctrine_Table_Exception' with message 'Unknown method BlogPostTable::getPopularTags' in C:\Users\user\www\extens.dev\tools\sandbox\lib\Doctrine\Table.php:2793
Stack trace:
#0 [internal function]: Doctrine_Table->__call('getPopularTags', Array)
#1 C:\Users\user\www\extens.dev\tools\sandbox\index.php(15): BlogPostTable->getPopularTags()
#2

{main}
thrown in C:\Users\user\www\extens.dev\tools\sandbox\lib\Doctrine\Table.php on line 2793
Fatal error: Uncaught exception 'Doctrine_Table_Exception' with message 'Unknown method BlogPostTable::getPopularTags' in C:\Users\user\www\extens.dev\tools\sandbox\lib\Doctrine\Table.php:2793
Stack trace:
#0 [internal function]: Doctrine_Table->__call('getPopularTags', Array)
#1 C:\Users\user\www\extens.dev\tools\sandbox\index.php(15): BlogPostTable->getPopularTags()
#2 {main}

thrown in C:\Users\user\www\extens.dev\tools\sandbox\lib\Doctrine\Table.php on line 2793

And here is the generated SQL:

CREATE TABLE taggable_tag (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(255) UNIQUE);
CREATE TABLE blog_post_taggable_tag (id INTEGER, tag_id INTEGER, PRIMARY KEY(id, tag_id));
CREATE TABLE blog_post (id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL);

Comment by Jonathan H. Wage [ 12/Nov/09 ]

When I test your code, it is working for me. You sure you don't have some old versions of PHP or something?

Comment by admirau [ 12/Nov/09 ]

Everything is up to date.
Tested on different servers, with different operating systems, different versions PHP, different versions of Doctrine, by different people.

Common thing for all these machines is that PHP (>5.2.10 <= 5.3.1) was installed from precompiled builds, not from source.

The error I get now is the same error I got earlier (at the beginning of this topic), which disapperared after your fix.
Then appeared the second error, which was fixed in BETA2, but the previous error is back. (strange, but the tests are passing now, despite the errors in the regular code).

When I find some spare time I'll try to trace the changes you've made since the beginning of the topic.

Comment by admirau [ 18/Nov/09 ]

Maybe the models are generated not properly.
Here are my models (three) for the reproduction procedure (above):

class BlogPostTable extends Doctrine_Table {}

class BlogPost extends BaseBlogPost {}

abstract class BaseBlogPost extends Doctrine_Record
{
public function setTableDefinition()

{ $this->setTableName('blog_post'); $this->hasColumn('title', 'string', 255, array( 'type' => 'string', 'notnull' => true, 'length' => '255', )); $this->hasColumn('description', 'string', 255, array( 'type' => 'string', 'notnull' => true, 'length' => '255', )); }

public function setUp()

{ parent::setUp(); $taggable0 = new Doctrine_Template_Taggable(); $this->actAs($taggable0); }

}

Comment by Jonathan H. Wage [ 18/Nov/09 ]

I have everything generated the same as you.

Comment by Benjamin Arthur Lupton [ 21/Nov/09 ]

Also getting this. Using doctrine 1.2.0-beta3 and also tried with latest SVN. Taggable is latest available.

PHP 5.3.0 running on Zend Server version 5.0.0Beta2

Comment by admirau [ 24/Nov/09 ]

No changes after upgrade to 1.2.0-RC1.

Comment by admirau [ 24/Nov/09 ]

Maybe this helps somehow:

// Following line throws:
// Doctrine_Table_Exception: Unknown method Doctrine_Table::getPopularTags in /home/user/doctrine12rc1/lib/Doctrine/Table.php on line 2799
$tags = Doctrine::getTable('BlogPost')->getPopularTags();

// This line returns collection of tags, as expected
$tags = Doctrine::getTable('TaggableTag')->getPopularTags('BlogPost');

$rel = Doctrine::getTable('BlogPost')->getRelations(); // is int(2)
$rel = Doctrine::getTable('TagableTag')->getRelations(); // is int(2)

Comment by Brian Smith [ 16/Dec/09 ]

Symfony 1.3 SVN updated as of this post.

Ubuntu Karmic with PHP 5.3.1

I have installed Taggable in mysymfonyproject/lib/doctrine_extensions/Taggable

I have two example tables defined with Taggable:

Video:
actAs:

{ Taggable: ~, Timestampable: ~ }

columns:
id:

{ type: integer, primary: true, autoincrement: true }

content_id:

{ type: integer, notnull: true }

title:

{ type: string(255) }

description:

{ type: clob }

relations:
Content:

{ local: content_id, foreign: id }

Photo:
actAs:

{ Taggable: ~, Timestampable: ~ }

columns:
id:

{ type: integer, primary: true, autoincrement: true }

content_id:

{ type: integer, notnull: true }

title:

{ type: string(255) }

description:

{ type: clob }

uri:

{ type: string(255) }

relations:
Content:

{ local: content_id, foreign: id }

The following code functions and populates the database:
$video = new Video();
...
$video->setTags(implode(", ", $tags));
$video->save();

The following code errors:
$tags = Doctrine::getTable('Video')->getPopularTags();

500 | Internal Server Error | Doctrine_Table_Exception
Unknown method VideoTable::getPopularTags

The following code errors:
$tags = Doctrine::getTable('TaggableTag')->getPopularTags('Video');

500 | Internal Server Error | Doctrine_Exception
Couldn't find class TagableTag

Comment by Sorin Neacsu [ 20/Jan/10 ]

Dont know if its related to this issue or not, but for some reason Doctrine::getTable('TaggableTag') throws a "

{Doctrine_Exception}

Couldn't find class TaggableTag" exception

I understand that you would normally do this:
Doctrine::getTable('Video')->getTags()
but I just want plain access to the TaggableTag model and Doctrine doesnt seem to generate any model classess for TaggableTag

Comment by Jonathan H. Wage [ 01/Mar/10 ]

I have tested everything everyone has provided and it is all working for me. The only thing I can suggest now is that someone creates a Doctrine failing test case so that I can run it to see the failure.

Comment by Benjamin Arthur Lupton [ 01/Mar/10 ]

Will create a test case this weekend for this and a few other problems I've across (with fixes). Nothing more frustrating than not being able to reproduce a problem, so I feel your pain.

Comment by Ivar Nesje [ 02/Mar/10 ]

I think this bug i related to the bug in the documentation http://www.doctrine-project.org/jira/browse/DC-378 to get the popular tags you will first have to load the models you want the tags for.

// load models that you want the tags from
Doctrine::getTable('blog');
Doctrine::getTable('products');
// then you can get the tags for the models currently loaded
$tags = Doctrine::getTable('TaggableTag')->getPopularTags();
Comment by Brian Smith [ 07/Mar/10 ]

This works for me:

// load models that you want the tags from
Doctrine::getTable('blog');
Doctrine::getTable('products');
// then you can get the tags for the models currently loaded
$tags = Doctrine::getTable('TaggableTag')->getPopularTags();

Comment by Benjamin Arthur Lupton [ 01/Apr/10 ]

Okie... Creating test cases for this turned out to be more complicated than I can handle - myself not being that familiar with phpunit.
Although within the test it is written as:
$test = Doctrine::getTable('TaggableTag')->getPopularTags(array('ArticleTaggableTest', 'ArticleTaggableTest2'));
Rather than:
$test = Doctrine::getTable('ArticleTaggableTest')->getPopularTags();
which is what this problem is about.

Although I do believe I've nailed the source of the problem - as well as others I've experienced.

Having either of the above causes the system to fall down. I've applied a bunch of fixes/changes to taggable to ensure it works with my systems, such as http://sos.7dots.co.uk/ (still in staging) which uses all of the above mentioned problems, not sure how to do a diff but here is the file:
http://www.2shared.com/file/12385197/c5911e42/Taggable.html

Hope that helps some people. Any changes I've made code can come under the same licence as doctrine, so no worries there.

Comment by admirau [ 15/Apr/10 ]

With 1.2.2 there is some progress.
There was still 1 test failing (CASCADE),
but with the version:
http://www.2shared.com/file/12385197/c5911e42/Taggable.html
provided by Benjamin Arthur Lupton
all test are passing now.

But now when I run:
getTable('ArticleTaggableTest')->getPopularTags();
I get: ERROR: column "i2__1" does not exist

The failing query on PostgreSql is:

SELECT t.id AS t_id, t.name AS tname, COUNT(DISTINCT i.id) AS i_0,
(COUNT(DISTINCT i.id)) AS i__1
FROM taggable_tag t
LEFT JOIN cms_model_image_taggable_tag c ON (t.id = c.tag_id)
LEFT JOIN image i ON i.id = c.id
WHERE t.id IN
(SELECT doctrine_subquery_alias.id
FROM
(SELECT DISTINCT t2.id, (COUNT(DISTINCT i2.id)) AS i2__1
FROM taggable_tag t2
LEFT JOIN cms_model_image_taggable_tag c2 ON (t2.id = c2.tag_id)
LEFT JOIN image i2 ON i2.id = c2.id
GROUP BY t2.id HAVING i2__1 > 0
ORDER BY i2__1 DESC LIMIT 10) AS doctrine_subquery_alias)
GROUP BY t.id HAVING i__1 > 0
ORDER BY i__1 DESC

Seems that this just a PostgreSql issue.
On Mysql it runs just fine.

Comment by Ivar Nesje [ 15/Apr/10 ]

The last comment is concerning how the poular tags are found and rated (on PostgreSql). I think this is unrelated to the rest of this issue and should be moved to a separate issue. (also I only got junk ads when I tried to get the file you are linking to).

Comment by admirau [ 15/Apr/10 ]

I have created separated issue for this:
http://www.doctrine-project.org/jira/browse/DC-634

And yes, this link is quite odd...
There is a lot of crap,
however there is a small link, to download improved code:

Look for: "Save file to your PC: click here"





[DC-936] json schema import broken Created: 22/Nov/10  Updated: 22/Dec/10

Status: Open
Project: Doctrine 1
Component/s: File Parser
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Mael Nison Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3.3-1ubuntu9.1


Attachments: File foobar.schema.json    

 Description   

With a valid Json file :
PHP Warning: explode() expects parameter 2 to be string, object given in Doctrine/Doctrine/Import/Schema.php on line 381
PHP Catchable fatal error: Object of class stdClass could not be converted to string in Doctrine/Doctrine/Import/Schema.php on line 391

It's due to this line, line, in Doctrine/Parser/Json.php (#65) :
$json = json_decode($contents);

It should be:
$json = json_decode($contents, true);

Because casting the result as array will only affect the top-level element. You must use the second parameter of json_decode() to force every objects (including sub-objects) to be converted to indexed arrays.



 Comments   
Comment by Mael Nison [ 22/Nov/10 ]

A try to import this file should fail.

Comment by Brian Fenton [ 22/Dec/10 ]

I've submitted a pull request w/patch and unit test for this issue using the fix above. I had the same problem in my code on OS X 10.6.4, PHP 5.3.2





[DC-392] Let the parser ignore .* (hidden) files Created: 02/Jan/10  Updated: 08/Jun/10

Status: Open
Project: Doctrine 1
Component/s: File Parser
Affects Version/s: 1.1.6
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Alessandro Vermeulen Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When generating models from yml files starting with a `.' such as temporary files from certain editors and meta files from OS X are also parsed by the importer. I do not see any reasons too include these hidden files in parsing as they are hidden for a purpose. And there would be no point in deliberately using hidden files for your config files.

Also see:
http://blog.rajatpandit.com/2009/08/23/doctrine_parser_exception-fail-some-error-message/
and
http://alessandrovermeulen.me/2010/01/01/doctrine-unable-to-parse-string-unable-to-parse-line-0/



 Comments   
Comment by Alessandro Vermeulen [ 02/Jan/10 ]

Added affected versions.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

We can include this fix in 1.2.3, does anyone have a patch? If not I'll try and hunt down the offending code and patch it. Not sure where it is off the top of my head anymore





[DC-1014] Geographical behaviour generates wrong INSERT statement in PostgreSQL if latitude/logitude not specified Created: 01/Jul/11  Updated: 01/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Geographical
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Lorenzo Nicora Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symphony 1.4, PostgreSQL 8.4.8



 Description   

Added "Geographical" behaviour to an entity:

 
ZipCode:
  actAs: [Geographical]
  columns:
    code: string
    [...]

Using the standard Symfony-generated admin manager, when trying to insert a new record without specifying both latitude and longitude, Doctrine generates a wrong INSERT statement for PostgreSQL, including latitude and longitude as '' (empty string)

 
Doctrine_Connection->exec('INSERT INTO zip_code (hidden, code,  country_id, latitude, longitude) VALUES (?, ?, ?, ?, ?)', array('false', '20133', '1', '', ''))

This cause this error:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type double precision: ""

Workaround

explicitly specifying float type for latitude and longitude...

 
  actAs: 
    Geographical:
      latitude: {type: float}
      longitude: {type: float}

...still generate the column correctly as double precision in the database, but will not cause any error on inserting records.






[DC-806] i8n behavior Created: 31/Jul/10  Updated: 31/Jul/10

Status: Open
Project: Doctrine 1
Component/s: I18n
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Fabien MEYNARD Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 1.4.0, PHP 5.2.6 & 5.3.1


Attachments: PNG File Capture d’écran 2010-07-30 à 12.43.50.png    

 Description   

hi everyone

I'm trying to use the Doctrine i18n behavior but ... something wrong happen!

I have this Doctrine_Connection_Mysql_Exception :

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'p.label' in 'field list' ( ie : linked screenshot )

with this request :


Doctrine_Query::create()->from('OrderProduct o')
->leftJoin('o.Product p')
->addWhere('o.order_id = ?', $currentOrderId)
->orderBy('o.created_at ASC')
->execute();

I don't understand why doctrine try to get the label field from "Product", this field is in the Translation table :s

Here an extract from my schema.yml :

Product:
tableName: product
actAs:
I18n:
fields: [label, label_2]
columns:
code:

{type: string(64), notnull: true, primary: true}

label:

{type: string(64)}

label_2:

{type: string(64)}

i don't know if my problem is in my code ( i don't think ), in Doctrine or in Symfony implementation of doctrine and thats why i post this message.

If you want more details ask me I have one working copy "freezed" just for this bug ( and for my work i use a system without i18n behavior :s )

thx in advance






[DC-779] sf1.4 i18n form create/update item extra insert Created: 08/Jul/10  Updated: 14/Oct/10

Status: Open
Project: Doctrine 1
Component/s: I18n
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Tim Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

problem arises \w Symfony 1.4.6 on Mac OS X 10.6.4 with Mysql 5.1.38 and a also on Ubuntu 10.04 Lucid \w bundled Apache 2.2.14 and Mysql 5.1.41



 Description   

config/doctrine/schema.yml:
JobeetCategory:
actAs:
Timestampable: ~
I18n:
fields: [name]
columns:
id:
type: integer(4)
primary: true
autoincrement: true
num:
type: integer(4)
name:
type: string(255)
notnull: true

lib/form/doctrine/JobeetCategoryForm.class.php:
class JobeetCategoryForm extends BaseJobeetCategoryForm
{
public function configure()

{ $this->embedI18n(array('nl')); }

}

then running:
./symfony doctrine:generate-module --non-verbose-templates --with-show backend category JobeetCategory

surfing to:
backend_dev.php/category/new

everything looks fine but as soon as I post valid data i get the following error:
500 | Internal Server Error | Doctrine_Connection_Mysql_Exception
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-nl' for key 'PRIMARY'

And in my sql log i see it tries to execute the following (and fails):
START TRANSACTION
INSERT INTO `jobeet_category` (`created_at`, `updated_at`) VALUES ('2005-01-01 00:00:00', '2005-01-01 00:01:00')
INSERT INTO `jobeet_category_translation` (`id`, `lang`, `name`) VALUES ('1', 'nl', '2378')
INSERT INTO `jobeet_category_translation` (`id`, `lang`) VALUES ('1', 'nl_NL')
ROLLBACK

Obviously this third insert is not ok, but why is doctrine running it?

I tried the Jobeet demo locally to see if I get the same issues with editing the I18n categories in the backend, but that all runs fine..

I tried a apps/backend/config/settings.yml with:

  1. i18n
    i18n: true
    default_culture: nl
    standard_helpers: [Partial, I18N]

and I also tried it commenting it all out. Still doesn't work.

I really don't know why Doctrine runs this third insert and why it is using the incorrect "nl_NL" instead of "nl".



 Comments   
Comment by Jonathan Pasquier [ 14/Oct/10 ]

Hi,

I had the same problem, and was able to solve it setting the culture of the user.

In my case, I had two languages: "ca" and "es" (catalan and spanish), and my default culture defined in settings.yml was "ca_ES"

Every time I tried to save a symfony form with embeded translation forms, I got an error similar to the following one:
Integrity constraint violation: 1062 Duplicate entry '3-ca' for key 'PRIMARY'

Basically, symfony or Doctrine, was trying to do 3 inserts: one with the "ca" language, one with the "es" language and one with the "ca_ES" language!

Here is the symfony log:

Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Mysql} exec : SET NAMES 'UTF8' - ()
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : SELECT COUNT(*) AS num_results FROM client c WHERE c.id = ? - (1)
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : INSERT INTO campanya (client_id, idiomes, created_at, updated_at) VALUES (?, ?, ?, ?) - (1, a:1:{i:0;s:2:"ca";}, 2010-10-13 14:38:46, 2010-10-13 14:38:46)
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : SELECT c.id AS c__id, c.lang AS c__lang, c.slug AS c__slug FROM campanya_translation c WHERE (c.slug LIKE ? AND c.lang = ? AND c.nom = ?) - (aixo-es-una-nova-campanya-en-catala%, ca, Això és una nova campanya, en català)
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : INSERT INTO campanya_translation (id, lang, nom, descripcio, slug) VALUES (?, ?, ?, ?, ?) - (3, ca, Això és una nova campanya, en català, Lorem ipsum dolor...
Hic et nunc!, aixo-es-una-nova-campanya-en-catala)
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : SELECT c.id AS c__id, c.lang AS c__lang, c.slug AS c__slug FROM campanya_translation c WHERE (c.slug LIKE ? AND c.lang = ? AND c.nom = ?) - (%, es, )
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : INSERT INTO campanya_translation (id, lang, nom, descripcio, slug) VALUES (?, ?, ?, ?, ?) - (3, es, , , )
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : SELECT c.id AS c__id, c.lang AS c__lang, c.slug AS c__slug FROM campanya_translation c WHERE (c.slug LIKE ? AND c.lang = ? AND c.nom IS NULL) - (%, ca_ES)
Oct 13 14:38:46 symfony [info] {Doctrine_Connection_Statement} execute : INSERT INTO campanya_translation (id, lang, slug) VALUES (?, ?, ?) - (3, ca_ES, )
Oct 13 14:38:46 symfony [err] {Doctrine_Connection_Mysql_Exception} SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3-ca' for key 'PRIMARY'

Finally, I was able to solve it doing a:
$this->getUser()->setCulture('ca');
when users log into my application.

I'm using symfony 1.4.9





[DC-728] Updating slug in I18N behaviour yields non-unique slug Created: 11/Jun/10  Updated: 05/Oct/10

Status: Open
Project: Doctrine 1
Component/s: I18n, Sluggable
Affects Version/s: 1.2.0, 1.2.1, 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Florian Aschenbrenner Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 5
Labels: None
Environment:

Symfony 1.4.5
Doctrine ORM



 Description   

There seems to be a bug in the way, doctrine tries to find a unique slug for a table that is I18N-enabled and has a slug in it.

Following example:

Problem:
  actAs:
    I18n:
      fields: [name]
      actAs:
        Sluggable: { fields: [name], uniqueBy: [lang, name], canUpdate: true }
  columns:
    name: { type: string(255), notnull: true }

Now, if we insert a new entry, the slug get's created as expected. If we now insert another entry that would yield the same slug, the slug is made unique by adding the postfix as expected - all well so far.

Now, if we try to update the entry with the slug with the postfix, what i think is an error happens (Excerpt from Sluggable.php, lib/Doctrine/Template/Listener/Sluggable.php):

 
public function getUniqueSlug($record, $slugFromFields)
...
if ($record->exists()) {
            $identifier = $record->identifier();
            $whereString .= ' AND r.' . implode(' != ? AND r.', $table->getIdentifierColumnNames()) . ' != ?';
            $whereParams = array_merge($whereParams, array_values($identifier));
        }

        foreach ($this->_options['uniqueBy'] as $uniqueBy) {
            if (is_null($record->$uniqueBy)) {
                $whereString .= ' AND r.'.$uniqueBy.' IS NULL';
            } else {
                $whereString .= ' AND r.'.$uniqueBy.' = ?';
                $value = $record->$uniqueBy;
                if ($value instanceof Doctrine_Record) {
                    $value = current((array) $value->identifier());
                }
                $whereParams[] = $value;
            }
        }
...

So, the $record->exists() check evaluates to true and $table->getIdentifierColumnNames() yields the fields id and lang, so the whereString is something like

 
AND r.id != ? AND r.lang != ?

Now for the problematic part:
uniqueBy is lang and name; so the code adds to the whereString:

 
AND r.lang = ? AND r.name = ?

So the resulting whereString has something like

 
r.lang != ? AND r.lang = ?

which will never yield a result in my eyes, thus, the postfix is never incremented and the slug defaults to the the slug of name without postfix.



 Comments   
Comment by Rodrigo Borrego Bernabé [ 24/Jun/10 ]

Hi,

We've also found this problem and make a temporal workaround. But maybe our workaround can give someone an idea on how to fix the bug so I'm pasting the changed code here

In file sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Template\Listener\Sluggable.php (getUniqueSlug method)

Replace

if ($record->exists()) {
  $identifier = $record->identifier();
  $whereString .= ' AND r.' . implode(' != ? AND r.', $table->getIdentifierColumnNames()) . ' != ?';
  $whereParams = array_merge($whereParams, array_values($identifier));
}

With

if ($record->exists()) {
  $identifier = $record->identifier();
  $commonFields = array_uintersect($table->getIdentifierColumnNames(), $this->_options['uniqueBy'], "strcasecmp");
  foreach ($commonFields as $key => $value)
    unset ($identifier[$value]);
  
  $whereFields = array_diff($table->getIdentifierColumnNames(), $this->_options['uniqueBy']);
  $whereString .= ' AND r.' . implode(' != ? AND r.', $whereFields) . ' != ?';
  $whereParams = array_merge($whereParams, array_values($identifier));
}
Comment by Christian Seaman [ 05/Oct/10 ]

Rodrigo, I think the solution is simpler than you might expect...

The problem is that it is doing an AND where it should be doing an OR to find records other than the current one.

So, you just need to replace this part of Sluggable::getUniqueSlug():

Sluggable::getUniqueSlug()
...
        if ($record->exists()) {
            $identifier = $record->identifier();
            $whereString .= ' AND r.' . implode(' != ? AND r.', $table->getIdentifierColumnNames()) . ' != ?';
            $whereParams = array_merge($whereParams, array_values($identifier));
        }
...

With this code (the 3rd line has extra brackets and OR instead of AND):

Sluggable::getUniqueSlug() (modified)
        if ($record->exists()) {
            $identifier = $record->identifier();
            $whereString .= ' AND (r.' . implode(' != ? OR r.', $table->getIdentifierColumnNames()) . ' != ?)';
            $whereParams = array_merge($whereParams, array_values($identifier));
        }

In more detail, the WHERE clause being built up is saying:
"find me records WHERE (the slug begins with the same string) AND (it's not the same record) AND (the other key uniqueBy values are the same)"

However, to check that it's not the same record you just need one of the key values to be different (not all of them) so the check should be something like:

... AND (p.id != '2' OR p.lang != 'en') ...

instead of:

... AND p.id != '2' AND p.lang != 'en' ...

The modification to the code as stated above generates queries that look like this, which I'm pretty sure is correct:

... WHERE (p.url LIKE 'foo%' AND (p.id != '2' OR p.lang != 'en') AND p.lang = 'en' AND p.other_uniqueby_field = '1')

C





[DC-450] ORACLE: The generate DQL with i18n behavior doesn't correct Created: 25/Jan/10  Updated: 18/Mar/10

Status: Open
Project: Doctrine 1
Component/s: I18n
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Bertrand Zuchuat Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File DC450TestCase.php    

 Description   

My schema:

---
Country:
  tableName:          country
  actAs:
    SoftDelete:       ~
    Timestampable:    ~
    I18n:
      fields:         [name]
      className:      %CLASS%I18n
      tableName:      %TABLE%_i18n
      length:         5
  columns:
    id:
      type:           integer(3)
      primary:        true
      unsigned:       true
      sequence:       country
    created_at:
      type:           timestamp
    updated_at:
      type:           timestamp
    enabled_at:
      type:           timestamp
      notnull:        true
    disabled_at:
      type:           timestamp
    iso_code:
      type:           string(2)
    marc_code:
      type:           string(3)
    name:
      type:           string(255)
      notnull:        true

DQL query:

 
$country = Doctrine::getTable('Country')->findOneByMarcCode('sz');

Error:

 
ORA-00904: "C"."NAME": invalid identifier : SELECT a.* FROM ( SELECT c.id AS c__id, c.created_at AS c__created_at, c.updated_at AS c__updated_at, c.enabled_at AS 
c__enabled_at, c.disabled_at AS c__disabled_at, c.iso_code AS c__iso_code, c.marc_code AS c__marc_code, c.name AS c__name, c.deleted_at AS c__deleted_at FROM
common.country c WHERE (c.marc_code = :oci_b_var_1) ) a WHERE ROWNUM <= 1 

In this line, i show the field "name", but this field is in table translation. The DQL above is very complicated for only simple request. Why ?

Thank's

Bertrand



 Comments   
Comment by Bertrand Zuchuat [ 18/Mar/10 ]

I don't have a real connection on Oracle Server. This test doesn't return the error above.

Please test on real connection.

Thanks





[DC-443] Incorrect insert order in i18n entities Created: 22/Jan/10  Updated: 22/Jan/10

Status: Open
Project: Doctrine 1
Component/s: I18n, Relations
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Rodrigo Borrego Bernabé Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux (2.6.21 kernel)
Apache/2.2.6
PHP 5.2.6
symfony version 1.4.1
doctrine 1.2


Attachments: File i18nrelation_problem.tgz    

 Description   

If the schema has an entity MyMain with all its fields i18n and an entity MySecondary related to MyMain and you try to create a new MySecondary item using Symfony forms you get an error.

I think the error is doctrine and in i18n because if you remove a field from the i18n behavior (fields: [a,b,c,d], for example) all works ok.
I've included a symfony project to help developpers replicate the error.

My Schema

 
MyMain:
  actAs:
    I18n:
      fields: [a,b,c,d, e]
  columns:
    a:  { type: string(255), notnull: true }
    b:  { type: string(255), notnull: true }
    c:  string
    d:  string
    e:  string

MySecondary:
  columns:
    my_main_id:  integer
    a:        string(255)
    b:        string(255)
  relations:
    MyMain:
      local: my_main_id
      foreign: id
      foreignType: one
      cascade: [delete]

And the form code

class MyMainForm extends BaseMyMainForm
{
  public function configure()
  {
    $this->embedI18n(array('en', 'es'));
  }
}

class MySecondaryForm extends BaseMySecondaryForm
{
  public function configure()
  {
    $this->widgetSchema['my_main_id'] = new sfWidgetFormInputHidden();
    $this->embedRelation('MyMain as main_subform');
  }
}

And last the queries (and its order when you get the error)

INSERT INTO my_secondary (my_main_id, a, b) VALUES (?, ?, ?) - (, my_secondary[a], my_secondary[b])
INSERT INTO my_main_translation (id, lang, a, b, c, d, e) VALUES (?, ?, ?, ?, ?, ?, ?) - 
  (, en, my_secondary[main_subform][en][a], my_secondary[main_subform][en][b], my_secondary[main_subform][en][c], 
   my_secondary[main_subform][en][d], my_secondary[main_subform][en][e])
Error Doctrine_Connection_Mysql_Exception	SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id' cannot be null 





[DC-412] Error defining "unique" constraint in a translated (i18n) column Created: 09/Jan/10  Updated: 10/Jan/10

Status: Open
Project: Doctrine 1
Component/s: I18n
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: David Marín Carreño Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Let's suppose we have a class "Element" with columns "name" and "description".

We want to set an "unique" constraint in column "name", and set the I18n behavior to columns name and description.

In the generated translation table "element_translation", doctrine sets an unique constraint in the column "name". This is an error, as various languages could translate that string in the same way. I think that the "unique" constraint should be set to the combination of columns "name" and "lang", so the restriction applies for a given language.






[DC-372] I18n record generator assumes relation alias is the table name Created: 20/Dec/09  Updated: 20/Dec/09

Status: Open
Project: Doctrine 1
Component/s: I18n
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: thibault duplessis Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

latest symfony 1.4 SVN.



 Description   

In Doctrine/I18n.php, method setTableDefinition, line 108:

        foreach($relations as $table => $relation) {

But the $relations array key is not a table name, but a relation alias.

So currently the generator assumes the relation alias IS the table name.
When it's not true, the I18n table definition fails.






[DC-735] Imported objects not converted to objects and parsed as string when a setter method exists Created: 14/Jun/10  Updated: 22/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: