[DC-952] Non-Equal Nest Relations Not Working - from "Children" side Created: 03/Jan/11  Updated: 24/Mar/11

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

Type: Bug Priority: Blocker
Reporter: Paweł Barański Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 4
Labels: None
Environment:

Ubuntu 10.04 + PHP 5.3.3 + Symfony 1.4.8


Attachments: File DC952TestCase.php    
Sub-Tasks:
Key
Summary
Type
Status
Assignee
DC-958 updating Models with Intra-Table Rela... Sub-task Open Jonathan H. Wage  

 Description   

I've copy & pasted example from http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models/1_0#relationships:join-table-associations:self-referencing-nest-relations:non-equal-nest-relations .
I've created User backend module using doctrine:generate-admin backend User task. On how to reproduce the error:

1. Add 3 User objects (A,B,C)
2. Open generated edit form for User A.
3. Set User B as Children from Children list and Save
4. Set User B and C as Chidren from Children list and Save

As a result you will see only C set as Children, and strange situation in database :

UserReference Table:

parent_id | child_id
pk_B | pk_B (!!!)
pk_A | pk_C



 Comments   
Comment by Paweł Barański [ 06/Jan/11 ]

Same ticket on symfony trac because I'm not sure whose fault is it

http://trac.symfony-project.org/ticket/9398

Also some new error path there

Comment by Daniel Reiche [ 24/Mar/11 ]

Test Case of Non-Equal Self-Referencing Relations, based on #DC-329.

Failure occures in line 75 of the test case file. This should not happen!
Only the parent object is modified in line 73 and saving should not interfere with the relations.





[DC-770] Result Cache Created: 29/Jun/10  Updated: 29/Jun/10

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

Type: Bug Priority: Blocker
Reporter: Thomas Tourlourat - Armetiz Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Doctrine result cache isn't working properly.

Here a simple example, when I'm calling query->execute (); parentProgram is related to a video.
Into the Doctrine_Query_Abstract.php file

line 1014 : I have just add some code to output data.
[code]
if ($cached === false)

{ // cache miss $stmt = $this->_execute($params); $this->_hydrator->setQueryComponents($this->_queryComponents); $result = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliasMap); $oVideo = $result[0]; echo "not cached "; var_dump (count ($oVideo->parentProgram->getReferences ())); $cached = $this->getCachedForm($result); $cacheDriver->save($hash, $cached, $this->getResultCacheLifeSpan()); }

else

{ $result = $this->_constructQueryFromCache($cached); $oVideo = $result[0]; echo "cached "; var_dump (count ($oVideo->parentProgram->getReferences ())); exit (0); }

[/code]

The output of a query execution (the first with an empty APC cache) with "useResultCache" is :

  • not cached int(1)
  • cached int(0)

The problem is coming from the serialize php function that can't serialize protected properties..
getReferences is a getter to a protected property.. So data result can't work properly.

A solution could be use __sleep function, and a public property that contain all important protected data.






[DC-313] Ordering m2m relationship with column from related table (with orderBy option) Created: 02/Dec/09  Updated: 18/Feb/11

Status: Open
Project: Doctrine 1
Component/s: Record, Relations
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: Maciej Hołyszko Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 3
Labels: None
Environment:

php 5.3/win, doctrine 1.2 svn, ATTR_QUOTE_IDENTIFIER = true, ATTR_USE_DQL_CALLBACKS = true


Attachments: File DC313TestCase.php    

 Description   

I find no way to define automatic orderBy in m2m relations with column not from reference table, but actual related table.

E.g. BlogPost <= m2m through BlogPostCategory => BlogCategory
I need BlogPost->Categories ordered by BlogCategory.name

class BlogPost extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('title', 'string', 128);
        $this->hasColumn('content', 'string');
    }
    
    public function setUp()
    {
        $this->hasMany('BlogCategory as BlogCategories', array('local' => 'id_blog_post', 'foreign' => 'id_blog_category', 'refClass' => 'BlogPostCategory', 'orderBy' => 'name'));        
    }
}

class BlogCategory extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('name', 'string', 128);
    }
    
    public function setUp()
    {
        $this->hasMany('BlogPost as BlogPosts', array('local' => 'id_blog_category', 'foreign' => 'id_blog_post', 'refClass' => 'BlogPostCategory'));
    }
}

class BlogPostCategory extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('id_blog_post', 'integer', null, array('primary' => true));
        $this->hasColumn('id_blog_category', 'integer', null, array('primary' => true));
    }
    
    public function setUp()
    {
        $this->hasOne('BlogPost', array('local' => 'id_blog_post', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
        $this->hasOne('BlogCategory', array('local' => 'id_blog_category', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
    }
}

The resulting query contains doubled 'name' column in ORDER BY clause, both from reference table and related table, e.g. ORDER BY t2.name, t3.name

I tried putting the following code in BlogCategory::setTableDefinition() instead of attribute in relation definition in BlogPost record:

$this->option('orderBy', 'name');

but the result was the same.

Maybe I'm doing something wrong? Is there a possibility to define an alias, where to get column name from - in orderBy attribute?

Thanks in advance.



 Comments   
Comment by Maciej Hołyszko [ 02/Dec/09 ]

Attached test case.

Comment by Maciej Hołyszko [ 08/Dec/09 ]

I find this issue as critical one now, because when I use e.g.

$this->option('orderBy', 'name');

in a model's definition (not ref class), then when other model is related m2m with it, a query loading both of them with relations will fail because of name column duplicated in ref table.

Comment by suhock [ 23/Apr/10 ]

I am having the same issue with an equivalent test case. For some reason, the 'orderBy' option on the target of the join (set by calling the option() function inside the setUp() method of the model class, not the ref class) is being applied to the relation table. After digging through the 1.2.2 tag a bit, I found altering line 1319 of Query.php as follows seems to fix the problem (at least against my test cases):

if (isset($map['relation'])) {
if (isset($map['relation']) && $map['relation']->getTable() === $map['table']) {

I'll do some more thorough testing and submit a patch if I find time.

Comment by Bart W [ 17/Feb/11 ]

I had this issue as well. suhock's solution fixed it for me. It would be nice if this was merged in to a bug fix release of Doctrine 1.x.

Comment by suhock [ 18/Feb/11 ]

I ended up creating a new ticket, DC-651, which addresses a more general problem with the orderBy feature. You should use the attached Ticket_DC651.patch instead, as I found the solution I provided here is not completely correct and does not pass all test cases.





[DC-857] postHydrate not called for One to One relations, when ATTR_HYDRATE_OVERWRITE == false, and the record is cached in the table's identityMap Created: 03/Sep/10  Updated: 05/Sep/10

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

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

All


Attachments: Text File DC857.patch     File DC857TestCase.php    

 Description   

When objects are hydrated with a join to a one to one relation, if the queried object is stored in the table's cache, and ATTR_HYDRATE_OVERWRITE set to false, then the one to one relation's postHydrate method will never be called.

This is due to this line.

 
} else if ( ! isset($prev[$parent][$relationAlias])) {

...which will always evaluate to false, and postHydrate will ever be called, as the record has been pulled from the table cache here



 Comments   
Comment by Ben Davies [ 03/Sep/10 ]

Test case attached.

Comment by Ben Davies [ 03/Sep/10 ]

There needs to be some kind of caching on the pre/postHydrate calls, which is done throughout the Doctrine_Hydrator_Graph, except for when the relation is one-to-one.
This is done just above, for relations that are not one-to-one.

Unfortunately, I couldn't work out how to implement it for one-to-one.
Probably a simple fix for someone familiar with the code

Comment by Ben Davies [ 03/Sep/10 ]

Correct Test Case

Comment by Ben Davies [ 03/Sep/10 ]

Correct Test Case

Comment by Ben Davies [ 05/Sep/10 ]

I was probably a little too tired to think this through clearly on a Friday after a long weeks work!
Patched attached, which doesn't break any of the existing unit tests.





[DC-815] Model's default sorting breaks subqueries Created: 11/Aug/10  Updated: 14/Mar/11

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

Type: Bug Priority: Critical
Reporter: Jacek Jędrzejewski Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 1
Labels: None

Attachments: File DC9999TestCase.php    

 Description   

It works except subqueries. Main table's order is added to subquery and vice versa. SQL query looks like this:

{{
SELECT t.id AS t_id FROM ticket_d_c9999_record t WHERE (t.id = (SELECT MAX(t2.id) AS t20 FROM ticket_d_c9999__record t2 ORDER BY t.id ASC, t2.id ASC)) ORDER BY t.id ASC, t2.id ASC
}}

Query fails because there is >>no such column "t.id"<<.

I include a testcase when it is all visible.

BTW. there is nothing about that feature (and relation orderBy) in docs. It is only in UPGRADE file.



 Comments   
Comment by Jacek Jędrzejewski [ 25/Aug/10 ]

Anyone?

Comment by Alan Betteridge [ 10/Mar/11 ]

Am having the same issue!

Eventually found the orderBy option on both the model and on relationships and was over joyed as I'd been trying to find a way of doing this, but it didn't work!!

Found the patch http://www.doctrine-project.org/jira/browse/DC-651 which solved the first problem I encountered but now I'm getting this.

Comment by Alan Betteridge [ 14/Mar/11 ]

Had a look at the code and tried only setting the orderBy if the current component is actually referenced in the from sql part of the query.

Looking at what is selected from, $this->_sqlParts['from'], it appears that the main table ($map['table']->getTableName()) and $sqlAlias is include with a zero index and joined tables are keyed by their $alias (or at least the content of these variables within the loop).

From this I believe I could detect if the current entry in the loop was from a table that was in the current "FROM" part of the query by looking for the table name and alias as an entry or the current alias as a key in the "FROM" array.

Within my sub query the orderBy valeus would still get applied but only in the subquery and not in the main query where they were included before, out of scope.

With patch DC-651 applied my code in Query.php at line 1315 noew looks as follows:


                // Note: Only include orderBy values for tables we're actually selecting from (both the root table or
                // tables referenced from it)
                if (in_array("{$map['table']->getTableName()} {$sqlAlias}", $this->_sqlParts['from']) || array_key_exists($alias, $this->_sqlParts['from'])) {
                    if (isset($map['relation'])) {
                        if (isset($map['ref'])) {
                            $orderBy = $map['relation']['refTable']->processOrderBy($sqlAlias, $map['relation']['orderBy'], true);
                            if ($map['relation']['orderBy'] && $orderBy == $map['relation']['orderBy']) {
                                $orderBy = $map['relation']->getOrderByStatement($sqlAlias, true);
                            }
                        } else {
                            $orderBy = $map['relation']->getOrderByStatement($sqlAlias, true);
                            if ($orderBy == $map['relation']['orderBy']) {
                                $orderBy = null;
                            }
                        }
                    } else {
                        $orderBy = $map['table']->getOrderByStatement($sqlAlias, true);
                    }
                } else {
                        $orderBy = null;
                }

Am I correct in my assumptions?





[DC-725] Call record->get('RelationManyToManyName', FALSE) corrupt the record and generate a exception when calling record->save() Created: 09/Jun/10  Updated: 09/Jun/10

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

Type: Bug Priority: Critical
Reporter: David Jeanmonod Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22)
mysql Ver 14.14 Distrib 5.1.41, for apple-darwin9.5.0 (i386) using readline 5.1
Doctrine version 1.2.2 from SVN: http://doctrine.mirror.svn.symfony-project.com/tags/1.2.2/lib/Doctrine.php


Attachments: File get_with_no_load_corrupt_many_to_many_assoc_.php    

 Description   

Imagine a simple case. Contact can have many categories.
Doing thoses calls:

$c = Doctrine::getTable('Contact')->findOneById($id);
$c->get('Categories', false);
$c->save();

Generate the following error

PHP Fatal error:  Call to a member function save() on a non-object in /lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php on line 443
PHP Stack trace:
PHP   1. {main}() /test/doctrine/get_with_no_load_corrupt_many_to_many_assoc_.php:0
PHP   2. Doctrine_Record->save() /test/doctrine/get_with_no_load_corrupt_many_to_many_assoc_.php:51
PHP   3. Doctrine_Connection_UnitOfWork->saveGraph() /lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php:1705
PHP   4. Doctrine_Connection_UnitOfWork->saveAssociations() /lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php:137


 Comments   
Comment by David Jeanmonod [ 09/Jun/10 ]

Test case for the bug





[DC-489] Doctrine_Record seems to have a bug with default values when updating Created: 10/Feb/10  Updated: 20/Jan/11

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

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

PHP 5.2.11



 Description   

So lets see the table:

User:
tableName: users
columns:
id:
type: integer(1)
fixed: false
unsigned: true
primary: true
autoincrement: true
username:
type: string(32)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
password:
type: string(48)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
role:
type: enum
fixed: false
unsigned: false
values:

  • admin
  • support
    default: support <----- Unable to render embedded object: File (ROOT OF EVIL) not found.
    primary: false
    notnull: true
    autoincrement: false

So lets say we have a user with `role` = 'support' and want to set em
'admin' we wrote

$user = new App_Model_User();
$user->assignIdentifier(1);
$user->role = 'admin';
$user->save();
var_dump($user->toArray());

in debugger we see SQL query been made:

  1. [0.55 ms] UPDATE users SET role = ? WHERE id = ?
  • bindings: admin
  • 1

array(6)

{ ["id"]=> int(1) ["display_name"]=> string(13) "Administrator" ["username"]=> string(4) "root" ["password"]=> string(40) "45bb0f589525a2f0f2a48620bb59b1b8baef0c1d" ["role"]=> string(5) "admin" ["is_active"]=> bool(true) }

Superb! Works as it should! So lets now set role of this user back to
'support':

$user = new App_Model_User();
$user->assignIdentifier(1);
$user->role = 'support'; // This value defined as default in scheme,
thats why have problems
$user->save();
var_dump($user->toArray());

in debugger we didnot see any UPDATE queries! However object is been
changed, results just has not been flushed to database.

array(6)

{ ["id"]=> int(1) ["display_name"]=> string(13) "Administrator" ["username"]=> string(4) "root" ["password"]=> string(40) "45bb0f589525a2f0f2a48620bb59b1b8baef0c1d" ["role"]=> string(7) "support" ["is_active"]=> bool(true) }

I cant overcome this problem right now, unfortunatelly (well I can
just remove all default values from table definitions or use
Doctrine_Query for updating staff.. but I'd like to use models

However if I use Doctrine_Query of even

$user = Doctrine_Core::getTable('App_Model_User')->find(1);

instead of

$user = new App_Model_User();
$user->assignIdentifier(1);

updates works well...



 Comments   
Comment by Petr Peller [ 20/Jan/11 ]

I second this.

When you UPDATE row with save() method of Record after setting identifier by assignIdentifier() doctrine removes columns updates from SQL which are set to default values same as it would do with INSERT. Other columns are updated correctly. This is sure a bug.

You can workaround this by setting the value as NULL instead of the actual default value. (Which I wouldn't recommend).





[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-1060] Datetime Fomatting not working on findId in DB2 Platform Created: 24/Sep/13  Updated: 24/Sep/13

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

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

In DB2/Symfony2


Attachments: PNG File Screen Shot 2013-09-24 at 3.55.44 PM.png     PNG File Screen Shot 2013-09-24 at 3.56.13 PM.png    

 Description   

We had to put this fix to check for DateTimeTz in SimpleObjectHydartor to make it work for DB2. Same code works for mysql. Is it possible to put a fix as part of release of next Doctrine so we need not update vendor code locally.
if (isset($cache[$column]['field'])) {
$type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
if ($type == 'DateTimeTz')

{ $value = substr($value, 0, 19); }

$value = $type->convertToPHPValue($value, $this->_platform);
}

The error happens when we do a find($id) in
$ep = $em->getRepository('some name')->find($id);






[DC-1056] Doctrine is not compatible with PHP 5.4 due to change in serialize() behaviour. Created: 04/Jun/12  Updated: 06/Oct/13

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

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

PHP 5.4+


Attachments: Text File Record.php.patch    

 Description   

In PHP 5.4 there is a change in the way the object references are serialized:

Quote:
"Support for object references in recursive serialize() calls
Prior to PHP 5.4, object references where not saved in recursive serialize calls."

This minor change, breaks down serialization of collections when column of type "array" is present - double serialization occurs.
I'm attaching a patch fixing the issue.



 Comments   
Comment by Colin Darie [ 15/Oct/12 ]

I confirm for possible future readers: this patch works perfectly well. (cf github for several forks of doctrine with other bugfixes).

Comment by steven [ 27/Jan/13 ]

Hi all, does somebody knows where can I get a copy of the Doctrine 1.2.4 version but running on php 5.4?
Thise version you're talking about

Thanks

Comment by Marcin Gil [ 28/Jan/13 ]

I sent you URL to our private svn repo.

Comment by steven [ 28/Jan/13 ]

Thanks, you've saved mi life

Comment by Marcin Gil [ 06/Oct/13 ]

New, better patch.

Comment by Marcin Gil [ 06/Oct/13 ]

Hi, I have uploaded a better patch which resolved one more issue.

Comment by Christophe Coevoet [ 06/Oct/13 ]

Please use a pull request on github to submit a patch





[DC-1011] wierd behaviour with setTableName - table name doesn't get set Created: 28/Jun/11  Updated: 28/Jun/11

Status: Reopened
Project: Doctrine 1
Component/s: Record
Affects Version/s: 1.2.3
Fix Version/s: None

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

Linux 2.6.35-28-generic #50-Ubuntu SMP Fri Mar 18 19:00:26 UTC 2011 i686 GNU/Linux
PHP 5.3.3-1ubuntu9.5


Attachments: File attribute_set.php    

 Description   

if i create class called Attribute_set that extends Doctrine_Record and setTableName in setUpTableDefinintion like in documentation setting up models section, the table name appears not to be set
getTableName returns "doctrine_record_abstract"

any joins or relations fail.

if i set it in the setUp function the setTableName appear working and returns "attribute_sets" table name. This only happens with this particular class, and relations have no effect.

I attached class example i'm expiriencing problems with, that should help reproducte this issue



 Comments   
Comment by Justinas [ 28/Jun/11 ]

fixed misstype and it appears that it was not the problem, i get the same:

Base table or view not found: 1146 Table 'db.doctrine_record_abstract' doesn't exist

maybe attribute_set is somekind reserved word in doctrine library ?

Comment by Justinas [ 28/Jun/11 ]

the problem appears to come from Doctrine Formatter





[DC-979] Doctrine save() only checks one level deep on one-to-one relations. Created: 27/Feb/11  Updated: 27/Feb/11

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

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

MySQL 5.1.38, PHP 5.3.3



 Description   

Updating/saving an object fails when trying to update the nth-level of an existing object/relation where n is more than one level away from the root node of one-to-one relation chain. For example, with the yaml model below the following does not update the name of the Company object:

Image->Product->Category->Company->name = "Acme".

If "Product" has no changes it appears to stop checking for changes there. If we do a save on a one-to-many relation chain such as the following, it works fine:

Company->Category->Product->Image->name = "image1.jpg"

I was able to fix this issue by modifying the saveRelatedLocalKeys() function in UnitOfWork.php to use isModified() with deep=true:

if ($obj instanceof Doctrine_Record && $obj->isModified(true)) {

This works but I'm not sure if changing this has any repercussions on more complex queries.


detect_relations: true
options:
collate: utf8_general_ci
charset: utf8
type: InnoDB

Company:
tableName: Company
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
name:
type: string(45)

Category:
tableName: Category
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
companyId:
type: integer(4)
notnull: true
name:
type: string(45)
relations:
Company:
class: Company
local: companyId
foreign: id
foreignAlias: categories
onDelete: cascade
onUpdate: cascade
indexes:
fk_Category_Company1:
fields: [companyId]

Product:
tableName: Product
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
categoryId:
type: integer(4)
notnull: true
name:
type: string(45)
relations:
Category:
class: Category
local: categoryId
foreign: id
foreignAlias: products
onDelete: cascade
onUpdate: cascade
indexes:
fk_Product_Category1:
fields: [categoryId]

Image:
tableName: Image
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
productId:
type: integer(4)
notnull: true
name:
type: string(45)
relations:
Product:
class: Product
local: productId
foreign: id
foreignAlias: images
onDelete: cascade
onUpdate: cascade
indexes:
fk_Image_Product1:
fields: [productId]






[DC-967] Problems with fetchArray() combined with leftJoin() by using aliases of columns Created: 13/Feb/11  Updated: 13/Feb/11

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

Type: Bug Priority: Major
Reporter: Arnoldas Lukasevicius Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony Framework v1.3.8, Windows 7



 Description   

They are some strange problems with hydration to array combined with aliases of columns and JOINS. Let's see this example:

$q = Doctrine_Query::create ()
->select('c.id AS id, c.path AS path, c.name AS name, cbc.product_count')
->from('Category c')
->leftJoin('c.CategoryBrowserCache cbc');

$categories = $q->fetchArray();

This example will throw exception: "The root class of the query (alias lc) must have at least one field selected."

OK. Let's change code a little bit. Let's add alias for cbc.product_count column too:

$q = Doctrine_Query::create ()
->select('c.id AS id, c.path AS path, c.name AS name, cbc.product_count AS product_count')
->from('Category c')
->leftJoin('c.CategoryBrowserCache cbc');

$categories = $q->fetchArray();
print_r($categories);

Now code executed without exception, BUT $q->fetchArray() returned only ONE (first) record hydrated to array. Other results were ignored.

Let's change code one more time:

$q = Doctrine_Query::create ()
->select('c.id, c.path, c.name, cbc.product_count AS product_count')
->from('Category c')
->leftJoin('c.CategoryBrowserCache cbc');
$categories = $q->fetchArray();
print_r($categories);

Like you see I just removed all aliases for columns for Category. Now code will be executed without exceptions, All results will be hydrated into array as expected to be. Actually the same result can be reached by removing at least one alias for any Category column.






[DC-961] Copy uses mutators but does not use accessors Created: 28/Jan/11  Updated: 28/Jan/11

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

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


 Description   

I have a column that contains a serialized string of data. The accessor for that column unserializes the data and the mutator serializes. When calling copy the accessor is not used but the mutator is causing the mutator to fail because it receives a string instead of an object as its value.

The lines of code creating this problem follow:

Record.php
 public function copy($deep = false)
 {
    $data = $this->_data; //does not use accessor
...
    $ret = $this->_table->create($data); // does use mutator
...
}

I have currently patched my copy function with the following:

// $data = $this->_data
$data = $this->toArray(false);





[DC-934] One-to-one relationship with cascading deletion and softdelete creates empty records Created: 21/Nov/10  Updated: 29/Nov/11

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

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

Ubuntu 10.10, PHP 5.3.3


Attachments: File testcase.php    

 Description   

When using softdelete behaviour with cascading deletion on a one-to-one relationship, Doctrine will create a 'child' record if it doesn't exist already, during the cascading deletion. Eg:

  • Models Foo, Bar, both SoftDelete
  • Foo hasOne Bar
  • $myFoo->delete()

Result is:

  • $myFoo->deleted_at is set correctly as expected
  • New Bar record is created & saved in the process (but is not set to deleted)

Is this expected behaviour? I've attached a test case script, tested against export from SVN of Doctrine 1.2.3 that demonstrates this.



 Comments   
Comment by marius [ 29/Nov/11 ]

I can confirm this issue on Ubuntu 11.10 PHP 5.3.6-13ubuntu3.2





[DC-908] Can't save Doctrine Expression AES_ENCRYPT into a utf8_general_ci field Created: 31/Oct/10  Updated: 31/Oct/10

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

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

Win XP



 Description   

$membre = new Model_TMembre();
$membre->password = new Doctrine_Expression("AES_ENCRYPT(\"".htmlspecialchars($password,ENT_QUOTES)."\",\""._MYSQL_CRYPT."\")");
$membre->save();

Doesn't works id password field is encoded into utf8_general_ci .

Works fine id password field is encoded into latin1 .






[DC-912] A method that can run in a model when the model is autoloaded Created: 01/Nov/10  Updated: 09/Nov/10

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

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

XP Xamp


Attachments: Text File DC_912_fix.patch    

 Description   

For my project I needed to be able to reassign connections to models when they are autoloaded – this had to be able to happen during a conservative model loading process before the models had been instantiated. My solution was to build in a hook to a "autoloadSetUp" method which can be attached to any model (or class that is the base for a model).

I will post my patch after I make a test case for it.

Will Ferrer



 Comments   
Comment by will ferrer [ 02/Nov/10 ]

made test case use a static method

Comment by will ferrer [ 09/Nov/10 ]

fixed some compatibility issues with the test case and other test cases





[DC-893] Using default value for bigint fields generates an error Created: 19/Oct/10  Updated: 25/Oct/10

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

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

Replicated on *nix using MySQL DB.



 Description   

A field defined as:
'user_id' => array(
   'type' => 'bigint',
   'length' => 22,
   'default' => 0,
),

Generates an error when create-tables is used:
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 ' [...] user_id bigint(22) DEFAULT , INDEX schedule_prize_id_idx (schedule_prize_id)[..]

The default value is not accounted for.



 Comments   
Comment by Paulo Vitor Reis [ 25/Oct/10 ]

20 is the length of the mysql bigint..





[DC-887] disabling deep option with toArray() drops relations in result Created: 13/Oct/10  Updated: 17/Apr/14

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

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

Attachments: Text File doctrine_toarray-deep_fix.patch    

 Description   

Using the toArray() on a Doctrine_Record object with the deep option set to true (default) correctly converts the whole object to an array including the relations.
But when the deep option is disabled the relations are not converted to array's (as expected) but they are lost, I would expect them to still be there in their original form (objects).

I've attached a fix. Another solution would be to add a flag that disables deep array conversion but enables relation persistence.






[DC-884] Doctrine_Collection::loadRelated uses getLocal instead of getLocalFieldName Created: 11/Oct/10  Updated: 18/Feb/13

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

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

Windows



 Description   

Having a camelcase fieldname with a lowercase column name causes loadRelated of doctrine collection to throw an unknown property error, fix:

Change

$rel     = $this->_table->getRelation($name);

        if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
            foreach ($this->data as $record) {
                $list[] = $record[$rel->getLocal()];
            }
        }

to:

$rel     = $this->_table->getRelation($name);

        if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
            foreach ($this->data as $record) {
                $list[] = $record[$rel->getLocalFieldName()];
            }
        }
public function populateRelated($name, Doctrine_Collection $coll)
    {
        $rel     = $this->_table->getRelation($name);
        $table   = $rel->getTable();
        $foreign = $rel->getForeign();
        $local   = $rel->getLocal();

to

public function populateRelated($name, Doctrine_Collection $coll)
    {
        $rel     = $this->_table->getRelation($name);
        $table   = $rel->getTable();
        $foreign = $rel->getForeignFieldName();
        $local   = $rel->getLocalFieldName();


 Comments   
Comment by Sebastian [ 12/Oct/11 ]

Now this is really poor. This trivial bug is known for over a year not but not yet fixed.

Fixing it would save millions of rainforrest trees because people would not have to rely on hundreds of lazy loading queries per page but start to use the getRelation() method.

Comment by Sebastian [ 18/Oct/12 ]

Two years now. :'-(

Comment by Mishal [ 18/Feb/13 ]

Another year, and all people are probably on Doctrine2.

But.... I just pushed your fix #DC-884 to my Doctrine1 fork, if you are interested.

https://github.com/mishal/doctrine1





[DC-882] Doctrine Collection FromArray doesn't adhere to KeyColumn Created: 09/Oct/10  Updated: 09/Oct/10

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

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


 Description   

Using the following in the base class:

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

Then executing a query to array the indexes of the entity are not that of the class field:

example:

array(
 0 => ..
 1 => ...
);

fix:

/**
     * Populate a Doctrine_Collection from an array of data
     *
     * @param string $array 
     * @return void
     */
    public function fromArray($array, $deep = true)
    {
        $data = array();
        foreach ($array as $rowKey => $row) {
            $this[$rowKey]->fromArray($row, $deep);
        }
    }

to

/**
     * Populate a Doctrine_Collection from an array of data
     *
     * @param string $array 
     * @return void
     */
    public function fromArray($array, $deep = true)
    {
        $data = array();
        $keyColumn = $this->keyColumn;
        foreach ($array as $rowKey => $row) {
            $rowKey = $keyColumn AND isset($row[$keyColumn]) ? $row[$keyColumn] : $rowKey;
            $this[$rowKey]->fromArray($row, $deep);
        }
    }





[DC-845] One of our Foreign Keys is not being inserted/passed Created: 27/Aug/10  Updated: 27/Aug/10

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

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

Linux ubuntu 2.6.31-22-generic #63-Ubuntu SMP Thu Aug 19 00:23:50 UTC 2010 x86_64 GNU/Linux
PHP 5.2.10-2ubuntu6.4 with Suhosin-Patch 0.9.7 (cli) (built: Jan 6 2010 22:56:44)
mysql Ver 14.14 Distrib 5.1.37, for debian-linux-gnu (x86_64) using EditLine wrapper



 Description   

We are working on a symfony/doctrine project and have come to a near halt on development.

We feel that now, it may be a bug/feature in doctrine, regarding foreign keys

Part of our model includes a join table that references three different table. Below is a diagram of what the model looks like, and the relevant portion of our schema.yml is at the bottom.

Image of our schema: http://imgur.com/dfFYI.png

We have a form that contains a set of embedded forms that attempt to create a new Person entry and add rows to the join table, adding items to the PersonName table as needed.

The form attempts to do this by creating and saving PersonName objects with NameType parameters, but are running into the problem of Doctrine not including that column when trying to do an insert into the join table.

Part of the problem seems to be caused by the Doctrine_Connection_UnitOfWork::saveAssociations method:

foreach ($v->getInsertDiff() as $r)

{ $assocRecord = $assocTable->create(); $assocRecord->set($assocTable->getFieldName($rel->getForeign()), $r); $assocRecord->set($assocTable->getFieldName($rel->getLocal()), $record); $this->saveGraph($assocRecord); }

Are we correct in understanding that this means that Doctrine 1.2 does not support tables with multiple foreign keys in this scenario?

Here is the relevant portion of schema.yml:

agPerson:
columns:
id:
primary: true
type: integer(5)
autoincrement: true
relations:
agPersonName:
class: agPersonName
refClass: agPersonMjAgPersonName
local: person_id
foreign: person_name_id
agPersonNameType:
class: agPersonNameType
refClass: agPersonMjAgPersonName
local: person_id
foreign: person_name_type_id
agPersonNameType:
columns:
id:
primary: true
type: integer(2)
autoincrement: true
person_name_type:
unique: true
type: string(30)
notnull: true
app_display:
default: 1
type: boolean
notnull: true
relations:
agPerson:
class: agPerson
refClass: agPersonMjAgPersonName
local: person_name_type_id
foreign: person_id
agPersonName:
class: agPersonName
refClass: agPersonMjAgPersonName
local: person_name_type_id
foreign: person_name_id
agPersonName:
columns:
id:
primary: true
type: integer(5)
autoincrement: true
person_name:
unique: true
type: string(64)
notnull: true
relations:
agPerson:
class: agPerson
refClass: agPersonMjAgPersonName
local: person_name_id
foreign: person_id
agPersonNameType:
class: agPersonNameType
refClass: agPersonMjAgPersonName
local: person_name_id
foreign: person_name_type_id
agPersonMjAgPersonName:
columns:
id:
primary: true
type: integer(5)
autoincrement: true
person_id:
type: integer(5)
notnull: true
person_name_id:
type: integer(5)
notnull: true
person_name_type_id:
type: integer(2)
notnull: true
is_primary:
type: boolean
notnull: true
indexes:
UX_ag_person_mj_ag_person_name:
fields: [person_name_id, person_name_type_id, person_id]
type: unique
relations:
agPerson:
local: person_id
foreign: id
agPersonName:
local: person_name_id
foreign: id
agPersonNameType:
local: person_name_type_id
foreign: id
actAs:
Timestampable:

As a caveat: we've noticed that sfdoctrineguard group table, has such a relationship:

mysql> describe sf_guard_user_group;
---------------------------------------+

Field Type Null Key Default Extra

---------------------------------------+

user_id int(11) NO PRI 0  
group_id int(11) NO PRI 0  
created_at datetime NO   NULL  
updated_at datetime NO   NULL  

---------------------------------------+

i.e. IT has two foreign keys taken into account






[DC-835] Inconsistent record validation on a notnull foreign key when the local relation is set Created: 19/Aug/10  Updated: 24/Aug/10

Status: Open
Project: Doctrine 1
Component/s: Record, Relations, Validators
Affects Version/s: 1.2.1
Fix Version/s: None

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

Attachments: Text File dc-835-patch.txt     File ForeignKeysTestCase.php    

 Description   

Doctrine_Validator_ForeignKeys_TestCase#testForeignKeyIsValidIfLocalRelationIsSet()

This test passes fine as is. But it fails if I make the following change:

public function testForeignKeyIsValidIfLocalRelationIsSet()
{
    //$person = new TestPerson();
    $address = new TestAddress();
        
    //$address->Person = $person;    
    $address->Person->first_name = "John";
        
    $table = $address->getTable();
    $errors = $table->validateField('person_id', $address->person_id, $address);
        
    $this->assertEqual(0, $errors->count());
}

The only difference is that instead of explicitly assigning $address->Person, I'm letting it happen automatically when assigning the first name. What is it about the property chaining when creating the related record that screws up doctrine's internal reference tracking?



 Comments   
Comment by Adam Huttler [ 19/Aug/10 ]

This is an existing test case for which I've added two tests. The first one fails, while the second passes. The first one captures the issue I'm experiencing.

Comment by Adam Huttler [ 24/Aug/10 ]

This patch augments the test file with the new test and also makes a change to Doctrine_Related_LocalKey that causes the test to pass.

Unfortunately, it causes another test to fail: 1072.

I don't fully understand test 1072, but it appears to be testing closely related behavior (i.e. relation chaining).

What do you think?





[DC-814] protected method _isValueModified returns wrong result Created: 10/Aug/10  Updated: 10/Aug/10

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

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

Apache/2.2.15 (Win64) PHP/5.3.2



 Description   
    protected function _isValueModified($type, $old, $new)
    {
        if ($new instanceof Doctrine_Expression) {
            return true;
        }

        if ($type == 'boolean' && (is_bool($old) || is_numeric($old)) && (is_bool($new) || is_numeric($new)) && $old == $new) {
            return false;
        } else if (in_array($type, array('decimal', 'float')) && is_numeric($old) && is_numeric($new)) {
            return $old * 100 != $new * 100;
        } else if (in_array($type, array('integer', 'int')) && is_numeric($old) && is_numeric($new)) {
            // getType($old) in many cases is always 'string' so using operator '!=='  is make no sense 
            // the only needed condition is already checked: i mean 'is_numeric'
            return $old !== $new;
        } else if ($type == 'timestamp' || $type == 'date') {
            $oldStrToTime = strtotime($old);
            $newStrToTime = strtotime($new);
            if ($oldStrToTime && $newStrToTime) {
                // the same here: it's make no sense to using '!==' - first and second variable are the same type 
                return $oldStrToTime !== $newStrToTime;
            } else {
                return $old !== $new;
            }
        } else {
            return $old !== $new;
        }
    }


 Comments   
Comment by Michał Strzelecki [ 10/Aug/10 ]

Using operator '!==' is make no sense. The result is wrong after that comparition.
The implication of that is wrong state of the record if it is id of relation hydrate after joins.





[DC-810] Doctrine relations: Doctrine_Record::fromArray() does not update local field when new linked record is created Created: 06/Aug/10  Updated: 06/Aug/10

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

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

$uname -a
Linux debianVM 2.6.30-2-686 #1 SMP Sat Sep 26 01:16:22 UTC 2009 i686 GNU/Linux

$php -v
PHP 5.2.11-1 with Suhosin-Patch 0.9.7 (cli) (built: Sep 20 2009 12:28:20)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
with Suhosin v0.9.29, Copyright (c) 2007, by SektionEins GmbH


Attachments: File doctrine1_bug.diff    

 Description   

Doctrine_Record::fromArray() does not update local field when new linked record is created.

Case:

1. I have a model1 with a hasOne relation to model2.

2. I have a record in model1 with no model2 related

3. Then i try to update model1 adding a new related model2 record using Doctrine_Record::fromArray(), model2 is created (Doctrine_Record::toArray() shows me the new row in model2, created and linked to model1)

4. When I save and refresh model1, relation disappear (local field on model1 who links to model2 is empty).

So it seems that Doctrine_Record::fromArray() doesn't recognize the change on model1 if I link it to a new foreign record. In fact if I modify some other field in model1, create and link a new model2 record, all works good!

Digging in Record.php I found a trick, Doctrine_Record::fromArray() doesn't update the state of the model when relations are touched, so I force record state to Doctrine_Record::STATE_DIRTY.

Diff file is attached, but it's still a workaround.






[DC-797] Records containing a one-to-one relation are hydrated as dirty/modified Created: 26/Jul/10  Updated: 06/Jul/11

Status: Open
Project: Doctrine 1
Component/s: Record, Relations
Affects Version/s: 1.2.2
Fix Version/s: None

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

Attachments: File Record.php.diff     File test.php    

 Description   

Attached is a self-contained 80 line test. In the test, Foo has an one to one relation to Bar. There is a null value in the foreign key column (at least one Foo without a Bar). And the relation is being used via this DQL:

Doctrine_Query::create()->from('Foo f')->leftJoin('f.Bar b')->execute();

At around line 254 of Doctrine_Hydrator_Graph/Graph.php, the hydrator sets the value of the relation column to Doctrine_Null if there is no related record:

$prev[$parent][$relationAlias] = $this->getNullPointer();

This causes Doctrine_Record to check if the value of the foreign key field was updated, which it does by calling Doctrine_Record::_isValueModified(). However, that method considers an update from null to Doctrine_Null as a modification. So, the record (and eventually the entire Collection returned) is marked as Doctrine_Record::STATE_DIRTY, even though it contains no modifications. This occurs during hydration, so the caller never sees the record as being clean.

The workaround I'm using is to subclass Doctrine_Record, and return false from _isValueModified() when moving from null to Doctrine_Null. But I think this could also be fixed in the hydrator.



 Comments   
Comment by Dominic Scheirlinck [ 15/Sep/10 ]

Patch is here: http://github.com/doctrine/doctrine1/pull/7

Comment by Dominic Scheirlinck [ 17/Oct/10 ]

New pull request, done on a topic branch this time (and rebased to be much nicer)

http://github.com/doctrine/doctrine1/pull/8

Comment by Derek Price [ 06/Jul/11 ]

Record.php.diff contains basically the patch Dominic attached but also makes sure that the internal property value is set regardless of whether the record is marked as dirty or not. Some code will break when the internal property value is left <unset> instead of Doctrine_Null.





[DC-774] Cannot fromArray a toArray with many to many records Created: 01/Jul/10  Updated: 01/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Record, Relations
Affects Version/s: 1.2.2
Fix Version/s: None

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

Attachments: Text File doctrine-link.patch    

 Description   

When working with a many to many record, if you toArray then synchronizeWithArray/fromArray the result - you get an exception.

This appears to be due to the fact that toArray returns collections of array(0 => false) (because a record is in a locked state) and fromArray will attempt to link() the refClass (which has multiple identifiers).

Here's a test that should show this behavior:

class Doctrine_Ticket_DC774_TestCase extends Doctrine_UnitTestCase
{
    public function prepareTables()
    {
        $this->tables[] = 'EntityAddress';
        $this->tables[] = 'Book';
        parent::prepareTables();
    }

    public function prepareData()
    {
        $user = new User();
        $user->name = 'TestUser';

        $address = new Address();
        $address->address = 'TestAddress';

        $user->Addresses[] = $address;
        
        $user->save();
    }

    public function testToArraySynchronizeWithManyToMany() {
        $user = Doctrine_Core::getTable('User')->findOneByName('TestUser');
        $user->refreshRelated();
        $user->synchronizeWithArray($user->toArray());
    }

    public function testToArrayFromManyToMany() {
        $user = Doctrine_Core::getTable('User')->findOneByName('TestUser');
        $user->refreshRelated();
        $user->fromArray($user->toArray());
    }
}



 Comments   
Comment by Jeff Chu [ 01/Jul/10 ]

I doubt this is the right way to fix this, but we wrote in a patch that has the link() function ignore relations that with multiple identifiers. I figured this would be alright since linking those in directly don't make too much sense anyways.

It seems to pass the doctrine test suite. I've attached the patch in case anyone is curious.





[DC-704] Where fields not escaped properly when deleting associations. Created: 25/May/10  Updated: 14/Jun/10

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

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

Debian 5, PHP 5.3, Symfony 1.4.4, sfDoctrinePlugin, Pgsql driver


Attachments: Text File diff.patch    

 Description   

We noticed that in both Doctrine/Record.php and Doctrine/Connection/UnitOfWork.php the fields in the where clause arent being escaped properly. A few of our fields happen to be keywords, but it seems that these queries arent escaping the names of fields that happen to be keywords.

I have verified the field name is in the keywords list for my driver.

This happens near the following code:
Doctrine/Record.php:2465
Doctrine/Record.php:2476
Doctrine/Connection/UnitOfWork.php: 443



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

Can you provide a patch with the changes?

Comment by Glenn R. Martin [ 14/Jun/10 ]

The following is the patch you requested. This is what WE did for our specific case to fix this... though it wont work with any other driver... What we really should have done (if I had been given time) was to pull the escape characters from the database driver so this would work on every database, not just Postgres.





[DC-684] After adding a Reference, the ForeignKeys in the DB are not updatet Created: 14/May/10  Updated: 26/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Record, Relations
Affects Version/s: 1.2.2
Fix Version/s: None

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

Ubuntu 9.04, PHP 5.2.6, MySQL 5.1, Zend Framework


Attachments: Text File DC_684_dirty_fix.patch    

 Description   

After query a record from the DB, where a foreign key is null, and changing only the reference belonging to this foreign key, and only these reference no other value of the record, a save of the record doesn't lead to a change in the foreign key field.

For example: I'll save a user record with some data of a regestration and give him the possibillity to add a city where he cames from later in his account settings, if no other user attribute is changed, the state of the user record is still CLEAN. The result is that I can access the user->City property correctly only as long as no refresh from the db is done. So the changing of the foreign key belonging to the city isn't persistent in the DB.

Example Code:
$user = new Model_User();
$user->firstName = md5(rand());
$user->save();

$id = $user->id;
unset($user);
assert(! $user);

$user = Model_UserTable::getInstance()->find($id);
assert(!$user->relatedExists('City'));

$user->City->name = 'Mainz';
$user->save();
unset($user);

$user = Model_UserTable::getInstance()->find($id);
$user->refresh(true);
assert($user->City->name == 'Mainz');

The last assert failse. I realized the problem while updating just a referenz using the fromArray() method like $user->City->fromArray(). The city would be saved correctly in DB but the foreign key in the user table would not be updated. After debugging I recognized that the $user is not replaced in UnitOfWork::saveGraph() because the $user is still in CLEAN state.

Using " $user->coreSetRelated('Country', $user->Country);" or "$user->state(Doctrine_Record::STATE_DIRTY);" after "$user->City->name = 'Mainz'" would fix the prob in this case. As well as creating a new City instance an set $user->City with this instance like:

$city = new Model_City();
$city->name = 'Mainz';
$user->City = $city;

Also $user->isModified(true) is true. So I fixed the issues in my case by changing the state of my records to DIRTY if the "$this->state() == CLEAN && $user->isModified(true) == true" in the preSave() method of an abstract class that my Base classes are extending....



 Comments   
Comment by Alexandre Ravey [ 15/Sep/10 ]

Spend the last hour trying to get a workaround on this one.

It apear to me that the solution is not easy. The object is modified while in STATE_LOCKED state, meaning that any state change in Record::_set() is not passed back to UnitOfWork::saveGraph() and therfor not saved in the database.

Finaly I've managed to make a realy dirty fix, I'll attach it if it come handy to somebody.
Keep in mind this is only a workaround and has NOT been tested. Use at your own risk...

Comment by Alexandre Ravey [ 15/Sep/10 ]

Dirty fix, see comments.
! NOT tested thoroughly !





[DC-649] Getting Doctrine_Validator_Exception on Doctrine_Record::replace() when using unique Created: 26/Apr/10  Updated: 26/Apr/10

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

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

PHP 5.3.2, MySQL 5.1.46



 Description   

Using this code:

$user = new User();
$user->mail = 'mail@mail.mail';
$user->save();
$user2 = new User();
$user2->mail = 'mail@mail.mail';
$user2->replace();

I get the following exception:

Fatal error: Uncaught exception 'Doctrine_Validator_Exception' with message 'Validation failed in class User: 1 field had validation error: 1 validator failed on mail (unique)' in D:\Workspace\Doctrine\Doctrine\Transaction.php:265
Stack trace:
#0 D:\Workspace\Doctrine\Doctrine\Connection.php(1395): Doctrine_Transaction->commit(NULL)
#1 D:\Workspace\Doctrine\Doctrine\Connection\UnitOfWork.php(143): Doctrine_Connection->commit()
#2 D:\Workspace\Doctrine\Doctrine\Record.php(1748): Doctrine_Connection_UnitOfWork->saveGraph(Object(User), true)
#3 D:\Workspace\test.php: Doctrine_Record->replace()
#4

{main}

thrown in D:\Workspace\Doctrine\Doctrine\Transaction.php on line 265






[DC-635] synchronizeWithArray and link-table Created: 16/Apr/10  Updated: 16/Apr/10

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

Type: Bug Priority: Major
Reporter: Thomas Tourlourat - Armetiz Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Tree tables : tags, compo_show_tag, shows

"compo_show_tag" make a link between tags and shows. It's a many-to-many relationship.

Assume that all the Tags / Shows are already create. The max id is 300 for shows and tags.

$itemArray = array ();
$itemArray["_identifier"] = 38;
$itemArray["shows"][0]["_identifier"] = 36;
$itemArray["shows"][1]["_identifier"] = 200;

$item = new Model_Tag ();
$item->synchronizeWithArray($itemArray, true);

echo $item->shows[0]->idShow; //Output : 36
echo $item->shows[1]->idShow; //Output : 200

$item->save ();

Above create two entry into the compo_show_table. Because all element are existing.

$itemArray = array ();
$itemArray["_identifier"] = 38;
$itemArray["shows"][0]["_identifier"] = 36;

$item = new Model_Tag ();
$item->synchronizeWithArray($itemArray, true);

echo $item->shows[0]->idShow; //Output : 36

$item->save ();

Above remove the relation between Show#200 and Tag#38, but keep the relation between Show#36 and Tag#38.

$itemArray = array ();
$itemArray["_identifier"] = 38;
$itemArray["shows"][0]["_identifier"] = 36;
$itemArray["shows"][1]["_identifier"] = 150;
$item = new Model_Tag ();
$item->synchronizeWithArray($itemArray, true);

echo $item->shows[0]->idShow; //Output : 36
echo $item->shows[1]->idShow; //Output : 150

$item->save ();

Above create a new relation, like the first example.

$itemArray = array ();
$itemArray["_identifier"] = 38;
$itemArray["shows"][0]["_identifier"] = 36;
$itemArray["shows"][1]["_identifier"] = 140;

$item = new Model_Tag ();
$item->synchronizeWithArray($itemArray, true);

echo $item->shows[0]->idShow; //Output : 36
echo $item->shows[1]->idShow; //Output : 140

$item->save ();

Bug is above.
We except that Doctrine remove the relation between Show#150 and Tag#38 and add a new one between Show#140 and Tag#38.
Here the bug because Doctrine doesn't change anything.

Thanks.
Armetiz.






[DC-619] preHydrate/postHydrate events do not use proper sub-class component Created: 06/Apr/10  Updated: 14/Jun/10

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

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

PHP 5.2.11 (cli), Doctrine 1.2 (Revision: 7537)



 Description   

I am trying to use preHydrate/postHydrate with my models that use inheritance. The problem is that when using the parent table is used to query the records, the preHydrate/postHydrate events are passed to the parent record class instead of the proper sub-class for the current record.

Using the example schema below, if I do a findAll() on the Person table and it contained two Student records and one Professor record... preHydrate would get called on Person instead of Student and Professor. This also applies for any listeners that are registered on Student/Professor and not Person.

Person:
columns:
name:

{ type: string(50) }

Student:
inheritance:
extends: Person
type: column_aggregation
keyField: type
keyType: 1

Professor:
inheritance:
extends: Person
type: column_aggregation
keyField: type
keyValue: 2






[DC-589] refreshRelated() causes an id to be changed from string to int, causing an unnecessary update query. Created: 19/Mar/10  Updated: 29/Mar/10

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

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

Ubuntu 9.10, PHP 5.2.10, pgsql 8.3



 Description   

Here is an example:

class Article extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('title', 'string', 255);
        $this->hasColumn('body', 'string', 4096);
    }

    public function setUp()
    {
        $this->hasMany('Comment as Comments', array(
            'local' => 'id',
            'foreign' => 'articleId',
        ));
    }
}

class Comment extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('comment', 'string', 4096);
        $this->hasColumn('articleId', 'integer');
    }

    public function setUp()
    {
        $this->hasOne('Article', array(
            'local' => 'articleId',
            'foreign' => 'id',
        ));
    }

    public function preUpdate($e)
    {
        throw new Exception('should not get here');
    }

}

$a = new Article();
$a->title = 'Hi';
$a->body = 'There';
$a->save();

$c = new Comment();
$c->comment = '1st comment';
$c->articleId = $a->id;
$c->save();

$a->refreshRelated('Comments');

$a->title = 'Hello';
$a->save();

What happens above is that the call to refreshRelated() causes the 'id' of the comment to change from string:1 to int:1, which causes the last save of the article to try to save the comment. The exception is there just to illustrate that the Comment is being updated (which should not happen). For us - this is an issue not just because of the extra query, but because some entities in the system (like log entries) actually throw when updated.

Tested against latest trunk.

The issue seems to be introduced in r7361.



 Comments   
Comment by Jonathan H. Wage [ 29/Mar/10 ]

How does that revision cause the problem? it doesn't change any value that is referenced by the object itself. Are you sure the description of the problem is accurate? Maybe it would be best if I could run a Doctrine failing test case to see your problem.





[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-476] PHP's is_subclass_of function causing failure in some contexts Created: 02/Feb/10  Updated: 30/Apr/10

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

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

php 5.2.10 on both CentOS 5.4 and Ubuntu 9.10



 Description   

I have a suspicion that this is related to issue: DC-386

The bug manifested its-self by bailing with no php error output when calling Doctrine_Pager::execute() in php 5.2.10 (5.3 appears to work - Mac OS X while 5.2.10 fail on ubuntu and centos).

I traced this down to Doctrine_Record::processPendingFields(), the offending line number is #477.

Interestingly, if I call is_subclass_of() with exactly the same params in my view just prior to calling Doctrine_Pager::execute() in my code, the error does not present its-self , i.e. I'b adding the following code :

is_subclass_of('Doctrine_Hydrator_RecordDriver', 'Doctrine_Hydrator_Graph');

It can also be avoided by calling Doctrine_Pager::getQuery()->getQuerySql(); and no doubt other code paths which change the environment in some way.






[DC-478] Having a default value in a decimal field in base class forces Doctrine to try to save an instance even if not required. Created: 04/Feb/10  Updated: 04/Feb/10

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

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

Linux, PHP 5.3



 Description   

I have 2 classes. Order and Branch. An Order class can have one or no branch assigned to it. My base class definition for a branch is simple. It just has a name.

The Order class has:
$this->hasColumn('branchId', 'integer');

and

$this->hasOne(
'Fds_Model_Branch as branch',
array(
'local' => 'branchId',
'foreign' => 'id',
)
);

The branch class had this:

$this->hasColumn('name', 'string', 50, array(
'notnull' => true,
'notblank' => true,
));

No hasMany relation back to Orders.

Using this setup, all my tests work.

I added this to the Branch class.
$this->hasColumn(
'localTax', 'decimal', null,
array(
'notnull' => true,
'default' => 0,
)
);

Now my tests fail with a validator error from the branch class for the name property whenever I try to save an order that has no branch associated to it. Pretty weird right? I mean, my order has no branch, and yet Doctrine tries to save one.

But if I change the definition of localTax to this:
$this->hasColumn('localTax', 'decimal');

Then my tests work as expected again. Problem is, I need to assign the default value of 0 to localTax instead of null.

Is this a bug?






[DC-453] Joined records stated as dirty (whereas they are not modified) Created: 26/Jan/10  Updated: 29/Jul/10

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

Type: Bug Priority: Major
Reporter: Benoît Guchet Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None


 Description   

When you retrieve records like this:

(Here I have Labels, that have Albums)

$lab = Doctrine::getTable('Label')->createQuery('lab')
->leftJoin('lab.Albums alb')
->select('lab.id, alb.id')
->where('lab.id = ?', 1)
->fetchOne();

$lab->state() is STATE_PROXY : it's ok, properties are not all loaded from the DB and the object is not modified

BUT $lab->Albums[0]->state() is STATE_DIRTY : why ? the object is not modified...

This causes real problems, because this way, joined objects unloaded properties are corrupted : it really behaves like they all are "null", and that's all. Their real values are never loaded from the DB.



 Comments   
Comment by Benoît Guchet [ 15/Mar/10 ]

No way to correct that ?

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

Can you provide a test case? are you sure it is dirty or you had the object instance prior to the query and it was dirty there?

Comment by Benoît Guchet [ 15/Mar/10 ]

Actually the given sample code is written to be a test case (Label/Albums can be any other basic Parent/Children relation).
You retrieve an object, join a child relation, selects only some fields from the children => those children are Dirty.

Yes I'm sure it is dirty, the Album object does not exist before that, the script does nothing else than this query. The object was born dirty, so to speak.

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

Sorry, I meant a Doctrine unit test case. Not just some pasted code in the issue.

Comment by Michał Strzelecki [ 29/Jul/10 ]

I have the same problem, but I have a deeper relation. The clue of it is that, that in Albums[0] is setting id of relation with lab.id (cause of that change STATE_DIRTY is set), and after that operation getModiefied method return array with one element
array(
id => lab.id
)

The bug is that, that in releted object after hydration setting releted id changing state of record -> it is wrong behavior, becaus nothing changed -> record has releted id with value, which is exactly the same as in DB.





[DC-326] Running out of memory while executing single record lookup. Created: 04/Dec/09  Updated: 07/Dec/09

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

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

Mac OS 10.5, Zend Server CE, PHP 5.3
Symfony 1.4



 Description   

I have the model class as follows:

schema.yml
options:
  collate: utf8_unicode_ci
  charset: utf8
  type: INNODB
Identity:
  tableName: Identity
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    username:
      type: string(50)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    email:
      type: string(50)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    password:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    created_at:
      name: created_at
      type: timestamp
      # default: CURRENT_TIMESTAMP
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    updated_at:
      name: updated_at
      type: timestamp
      fixed: false
      unsigned: false
      primary: false
      default: null
      notnull: false
      autoincrement: false
  relations:
    Roles:
      class: Role
      local: id
      foreign: ident_id
      type: many
    Token:
      local: id
      foreign: entity_id
      type: many
    Devices:
      class: Device
      local: id
      foreign: account_id
      type: many
    Rides:
      class: Ride
      local: id
      foreign: account_id
      type: many
    OwnGroups:
      class: CoachGroup
      local: id
      foreign: owner_id
      type: many
    GroupMemberships:
      class: GroupMembership
      local: id
      foreign: ident_id
      type: many
  actAs:
    Timestampable:
      created:
        name: created_at
        type: timestamp
        expression: NOW()
      update:
        onInsert: false
Role:
  tableName: Role
  columns:
    identId:
      name: ident_id
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: false
    role:
      type: string(50)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: false
  relations:
    Identity:
      onDelete: CASCADE
      onUpdate: CASCADE
      local: ident_id
      foreign: id
      foreignAlias: Roles
Token:
  tableName: Token
  columns:
    entity_id:
      name: entity_id
      type: integer(4)
      fixed: false
      unsigned: false
      notnull: true
      primary: false
      autoincrement: false
    token:
      name: token
      type: string(50)
      fixed: true
      unsigned: false
      primary: true
      default: ''
      notnull: true
      autoincrement: false
    type:
      type: enum(50)
      fixed: false
      unsigned: false
      values:
        - EMAIL_VERIFICATION
        - PASS_RESET
      primary: false
      default: EMAIL_VERIFICATION
      notnull: true
      autoincrement: false
    created_at:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    expires_at:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
  indexes:
    entity:
      fields: [entity_id]
  relations:
    Identity:
      onDelete: CASCADE
      onUpdate: CASCADE
      local: entity_id
      foreign: id
      type: one
  actAs:
    Timestampable:
      created:
        name: created_at
        type: timestamp
      updated:
        disabled: true

and my unit test for the model:

TokenModelTest.php
$t = new lime_test(3);
$t->diag("=== Token model test ===");

$t->info('Token creation =>');
$token = new Token();
$token->setEntityId(1);
$token->generateUniqueToken();

$t->info('Set valid token type...');
$token->setType(Token::TYPE_EMAIL_VERIFICATION);
try{
  $t->info('Saving the token...');
  $token->save();
  $t->pass('Token was saved successfully...');
}
catch(Exception $e){
  $t->is(($e instanceof Exception), true, $e->getMessage());
}

$t->isnt($token->getCreatedAt(), null, ' Creation datetime is set to '.$token->getCreatedAt().'...');

$t->info('Get this token from DB...');
$tokenFromDb = Doctrine::getTable('Token')->findOneByToken($token->getToken());

$t->info('Compare the two...');
$t->is($tokenFromDb->getEntityId(), $token->getEntityId(), 'Entity ID...');
$t->is($tokenFromDb->getToken(), $token->getToken(), 'Token string...');
$t->is($tokenFromDb->getType(), $token->getType(), 'Token string...');
$t->is($tokenFromDb->getCreatedAt(), $token->getCreatedAt(), 'Token creation date...');
$t->is($tokenFromDb->getExpiresAt(), $token->getExpiresAt(), 'Token expration date...');
$t->is($tokenFromDb->getExpiresAt(), null, 'Token expration date is null...');

$t->info('Delete token...');
$t->is($token->delete(), true, 'Successful deletion...');

On test execution on this line:

$tokenFromDb = Doctrine::getTable('Token')->findOneByToken($token->getToken());

I'm getting a fatal error:

ERROR
# === Token model test ===
> Token creation =>
> Set valid token type...
> Saving the token...
ok 1 - Token was saved successfully...
ok 2 -  Creation datetime is set to 2009-12-04 01:13:31...
> Get this token from DB...
PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 261900 bytes) in /ApacheWebServer/htdocs/Clients/enki/enkiweb/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Core.php on line 550

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 261900 bytes) in /ApacheWebServer/htdocs/Clients/enki/enkiweb/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Core.php on line 550


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

Anymore information? Not much I can really do right now. If you have some more information to help I can look at the problem again. A Doctrine test case would be helpful.





[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-1044] record Line 2430 Unlink method Warning: Illegal offset type in sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php on line 2459 Created: 05/Dec/11  Updated: 05/Dec/11

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

Type: Bug Priority: Minor
Reporter: Kyle Clarke Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None


 Description   

When you have a new unpersisted object and you call a method to a referenced object - when calling the unlink() method on referenced object the above error is called.

Warning: Illegal offset type in sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php on line 2459

eg

$foo = new foo();

$foo->getBar(); This call will bind a reference of Bar against the foo object.

$foo->unlink('bar');

As no objects are yet persisted, the unlink method tries to match ids on the objects that do not exist.






[DC-1018] Circular references to named entities break during data importing Created: 14/Jul/11  Updated: 17/Apr/14

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

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


 Description   

If the schema specifies that records relate to each other in both directions:

{{
Kitten:
columns:
basket_id: integer
relations:
Basket:
local: basket_id

Basket:
columns:
fluffiest_kitten_id: integer
relaitons:
FluffiestKitten:
type: one
class: Kitten
local: fluffiest_kitten_id
}}

Then a data dump for such a schema won't properly load one of the keys, e.g:

{{
Kitten:
Kitten1:
Basket: Basket1

Basket:
Basket1:
FluffiestKitten: Kitten1
}}

Will result in either fluffiest_kitten_id or basket_id being set to 0

See also ticket DC-555






[DC-950] Doctrine_Record magic _set() doesn't validate field type for timestamp/datetime/etc.. Created: 23/Dec/10  Updated: 24/Jan/11

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

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


 Description   

So I ran into this recently. the magic _set() in Doctrine_Record doesn't check/validate the type of the field. The use case is when you you do something like:
setCreatedAt(time()); This will not work correctly with date/time or timestamp types in Doctrine, even though Propel handles this fine. Also MYSQL will not throw an error with default sql_mode and will put garbage data into the database.

The only way to generate the right date/time value is to always format that string with the "right" format. This should be easier and can be easier if it supported either a timestamp (time() or a DateTime() object (just like Symfony plugin does for setDateTimeObject() function). This is just a few lines of code, let me know if I should attach a patch.

I would love to see the Doctrine_Record implement this functionality. There's a ton of results on frustrated users trying to figure out how to set the date/time values properly using Doctrine.



 Comments   
Comment by Gennady Feldman [ 24/Jan/11 ]

Symfony actually added a work around by writing another function "setDateTimeObject()" to set these fields in a more friendly way. Ideally I would love to see support for time() and date_create() natively in 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-776] $record->link('Alias', $id) throws an exception because of getIdentifier returns array, not string Created: 05/Jul/10  Updated: 05/Jul/10

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

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

Symfony 1.4.6-DEV


Sub-Tasks:
Key
Summary
Type
Status
Assignee
DC-775 $record->link('Alias', $id) throws an... Sub-task Resolved Jonathan H. Wage  

 Description   

I want to bookmark ads on my site. So i have Ads table, users table (sfDoctrineGuard) and a refclass Bookmarks. I've created an ajax link to an action, where i retrieved $ad object, $user_id and
$ad->link('Bookmarks', $user_id, true);
So I expected a record in a database to be created.

Bookmarks:
...
columns:
user_id:

{ type: integer(4), primary: true }

ad_id:

{ type: integer(4), primary: true }

relations:
sfGuardUser:

{ onDelete: CASCADE, local: user_id, foreign: id }

Ads:

{ onDelete: CASCADE, local: ad_id, foreign: ad_id }

As my Bookmarks table has 2 primary keys in the link method

if (count($ids) > 0)

{ $q->whereIn($rel->getTable()->getIdentifier(), array_values($this->identifier())); }

$rel->getTable()->getIdentifier() returned me an array('user_id', 'ad_id') instead of a string. So the query which was generated looked like
UPDATE bookmarks SET ad_id = ? WHERE (Array IN )
And Array is not the name of a column.

My schema:
http://pastie.org/private/2lr9gy1h3mtdwdsiwrwylq

I've solved an issue by creating a new Bookmark instance and saving it, but i presume that issue might distract someone.






[DC-749] Doctrine_Record#getMutators() triggers PHP notice Created: 17/Jun/10  Updated: 17/Jun/10

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

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

Doctrine SVN 1.2 r7676


Attachments: Text File DC-749.patch    

 Description   

When calling getMutators() on an instance of Doctrine_Record (eg. $user = new User();), if it hasn't any defined custom mutator yet, we get a

Notice: Undefined index: User in /[...]/Doctrine/Record.php on line 1312

whereas there's no error with getAccessors() (I suppose it was fixed for the second one but not copied to the first one).

Patch is really simple! please see attachment

Regards






[DC-686] postHydrate listener isn't called for related records Created: 17/May/10  Updated: 05/Sep/10

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

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

Debian


Attachments: File NewTestCase.php    

 Description   

I have model A which has a one-to-one relationship with model B. They both have a listener on them which does an action on postHydrate. When I load model A, the postHydrate is called successfully. However when I then load the related model B (via $oMyModelA->B; or whatever), the listener is not called. This is the same when using the hook on the model - A::postHydrate() is called but B::postHydrate() is not.

Unit test demonstrating this bug is attached.



 Comments   
Comment by Ben Davies [ 05/Sep/10 ]

This is invalid.
In the test case:

$r->Related->save();

doesn't create a blank record, thus there is never a relation to postHydrate





[DC-642] import/export Array Created: 22/Apr/10  Updated: 22/Apr/10

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

Type: Bug Priority: Minor
Reporter: Thomas Tourlourat - Armetiz Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Retreive an object "A" and some related object from the database.
Export it into an array.
Create an other instance of "A" and import array from the previous exported array.
Just save the new instance.

Doctrine re-create the object into DB. If you have some integrity constraint like primary key, you will see an SQL error.

In the following example with "video" and "tags", Doctrine want to re-create the video and tag objects.
The reason is that the exported array doesn't include the "_identifier" key.

In my mind, the problem show and other problem, that we are force to use the "identifier" or assignIdentifier on the Model domain object to work with an existing object.
Doctrine know the Primary key of all the model domain objects. Why Doctrine doesn't use the assignIdentifier when the user change the PK of the Model domain object... In this case, assignIdentifier could be into a private scope.

$oVideo = Doctrine_Query::create ()
->select ("video., tags.")
->from ("Model_Video video")
->leftJoin ("video.tags tags")
->where ("video.id_show = 500")
->fetchOne ();
$oVideoArray = $oVideo->toArray();
$oVideo->save ();

$oVideoBis = new Model_Video ();
$oVideoBis->fromArray($oVideoArray, true);
$oVideoArrayBis = $oVideo->toArray();
$oVideoBis->save ();






[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





Generated at Tue Sep 02 06:47:38 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.