[DC-136] Table->find() does not reset the modified field list Created: 23/Oct/09  Updated: 23/Oct/09  Resolved: 23/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Minor
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

I think I can best explain what is happening with the following code:

// Create some object in the database.
$instance = new Model();
$instance->field = "value 1";
$instance->save();
$id = $instance->id;

$table = Doctrine::getTable('Model');

// Load the object from the database.
$instance_a = $table->find($id);

// Modify a field. 
$instance_a->field = "value 2";
print $instance_a->field . "\n";     // prints "value 2";
print_r($instance_a->getModified()); // prints "field"

// Load the object again from the database, into a new variable.
$instance_b = $table->find($id);

// $instance_a and $instance_b now are the same object.
// The data is fresh data from the database.
print $instance_a->field . "\n"; // prints "value 1";
print $instance_b->field . "\n"; // prints "value 1";

// However, the modified field list was not reset.
print_r($instance_a->getModified()); // prints "field"
print_r($instance_b->getModified()); // prints "field"

So the fresh record from the database is incorrectly marked as dirty. Main result is that this will trigger database activity when saving a model to the database, while no field data was actually changed.






[DC-134] Parse error in lib/Doctrine/Cache/Xcache.php (missing ;) and delete() should be deleteCache() (patch included) Created: 23/Oct/09  Updated: 23/Oct/09  Resolved: 23/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.0-ALPHA3
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Critical
Reporter: Reko Tiira Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File Doctrine_Cache_Xcache.patch    

 Description   

Missing ; in saveCache() function and delete method should also be named deleteCache as in other drivers.
This prevents xcache driver from working as well as compiling Doctrine to single PHP file. Patch included to fix the issue.






[DC-131] "Fatal error: [] operator not supported for strings" when use Apc Cache Driver with Doctrine 1.2.0 ALPHA 3 Created: 22/Oct/09  Updated: 23/Oct/09  Resolved: 23/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Caching
Affects Version/s: 1.2.0-ALPHA3
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Olivier Sieffert Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

PHP 5.3 with APC 3.1.3p1 module, Apache 2.2.13, GNU/linux 2.6.27.7-smp - i686 Intel Pentium 4 CPU 3.20GHZ



 Description   

Fatal error: [] operator not supported for strings in /opt/httpd/lib/php/Doctrine/Cache/Driver.php on line 244

The fetch function return a string, not a array

I offer following modification :

File: Doctrine/Cache/Apc.php

public function fetch($id, $testCacheValidity = true)

{ $results = apc_fetch($this->_getKey($id)); //$results = (array) $results; // Drop this line //return $results[0]; // Drop this line return $results; // Add this line }




[DC-125] Searchable: batchUpdateIndex has a memory leak Created: 20/Oct/09  Updated: 20/Oct/09  Resolved: 20/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Searchable
Affects Version/s: 1.1.4
Fix Version/s: 1.0.13, 1.1.5, 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Justin Mazzi Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File doctrine.searchable-memory.patch    

 Description   

batchUpdateIndex leaks memory when indexing a table. It holds onto a copy of every row it indexes in memory. I've attached a patch that fixes this issue.






[DC-124] Doctrine_Inflector uses tabs in the class definition Created: 20/Oct/09  Updated: 21/Oct/09  Resolved: 20/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

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


 Comments   
Comment by Lukas Kahwe [ 21/Oct/09 ]

actually it seems a lot of files have tabs in them and a fair bit of trailing whitespace. i am fairly pedantic with that kind of stuff in my own code, so i have showing of whitespace characters enabled. should i open tickets for all of those? or maybe you can just do a search and replace? i might still have commit access .. so i could do this myself ..





[DC-117] Doctrine_Migration_Base: methods to set default table options Created: 17/Oct/09  Updated: 19/Oct/09  Resolved: 19/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Migrations
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Minor
Reporter: Dan Bettles Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

Darwin, PHP 5.3, MacBook


Attachments: File doctrinemigrationbase_default_table_options.diff    

 Description   

I have implemented a very small - and unobtrusive - change to Doctrine_Migration_Base that enables users to set application-level default table options for Doctrine_Migration_Base::createTable().

I implemented this change some time ago in a custom migration class. I wanted my migrations to always create INNODB and UTF-8-ready tables without having to always specify options. I blogged about it and others were interested.

In your boot script - for example - set default table options like:

Doctrine_Migration_Base::setDefaultTableOptions(array(
'type' => 'INNODB',
'charset' => 'utf8',
'collate' => 'utf8_unicode_ci',
));

The enclosed patch, which includes tests, was created against 1.2 r6535.

Thanks



 Comments   
Comment by Guilherme Blanco [ 19/Oct/09 ]

In revision 6540 I committed your suggested patch! Thanks!





[DC-113] The nextId method doesn't have a good path for non-existing sequences when autocreate is not enabled. Created: 16/Oct/09  Updated: 19/Oct/09  Resolved: 19/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Geographical
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Minor
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

With the current code, the return data is outside the method's documentation for @return and there will be a notice from PHP about $result being undefined.

Fixed with the following patch.

    public function nextId($seqName, $onDemand = true)
    {
        $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true);

        $query = "SELECT NEXTVAL('" . $sequenceName . "')";
        try {
            $result = (int) $this->conn->fetchOne($query);
        } catch(Doctrine_Connection_Exception $e) {
            if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {

                try {
                    $result = $this->conn->export->createSequence($seqName);
                } catch(Doctrine_Exception $e) {
                    throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created');
                }
                return $this->nextId($seqName, false);
+           } else {
+             throw new Doctrine_Sequence_Exception('sequence ' .$seqName . ' does not exist');
            }
        }
        return $result;
    }


 Comments   
Comment by Guilherme Blanco [ 19/Oct/09 ]

Issue fixed for 1.2 =)





[DC-112] Improve result cache Created: 15/Oct/09  Updated: 23/Oct/09  Resolved: 23/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Major
Reporter: Jonathan H. Wage Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Reference
relates to DDC-47 Improve query resultset cache control Closed

 Description   

We need better control for setting the hash/key for resultset cache entries. Then provide a way to clear these cache entries.

http://trac.doctrine-project.org/ticket/2042

$temp = Doctrine_Query::create() 
->from('Profile p') 
->where('p.id=?', $o) 
->setHydrationMode(Doctrine::HYDRATE_ARRAY) 
->useResultCache(true, 3600, 'product_cache') // custom tag 
->execute(); 

$temp = Doctrine_Query::create() 
->from('Model m') 
->setHydrationMode(Doctrine::HYDRATE_ARRAY) 
->useResultCache(true, 3600, 'product_cache') // custom tag 
->execute(); 

$temp = Doctrine_Query::create() 
->from('News n') 
->setHydrationMode(Doctrine::HYDRATE_ARRAY) 
->useResultCache(true, 3600, 'news_cache') // custom tag 
->execute(); 

and now

$conn  = Doctrine_Manager::getConnection('sqlite_cache_connection'); 
$cacheDriver = new Doctrine_Cache_Db(array('connection' => $conn, 
'tableName' => 'cache')); 

$cacheDriver->deleteByTag('product_cache');


 Comments   
Comment by Michael Roterman [ 15/Oct/09 ]

Would an use case as followed be also considered?

$temp = Doctrine_Query::create()
->from('Model m')
->setHydrationMode(Doctrine::HYDRATE_ARRAY)
->useResultCache(true, 3600,array('product_cache', 'product_clean')) // custom array with tags
->execute();

So multiple tags could be used as "labels" for an cache instance?

Comment by Jonathan H. Wage [ 15/Oct/09 ]

Not really. The cache drivers only have the ability to store key => value pairs so we're limited on what we can provide in Doctrine natively.

Comment by Miloslav "adrive" Kmet [ 17/Oct/09 ]

I think, that each driver should store also cache metadata (that's the behaviour of symfony's cache system)..

In the cache should be sotred also the cache_info key that should be an array of cached keys each index of an array should be the tag name and each tagname should contain multiple cached_keys.

{{

{ $cacheInfo = array( 'product_cache' => array('sql_1_key', 'sql_1_key_paged', 'sql_2_key', 'etc' ,'etc'), 'brands_cache' => array('sq_1_key', 'sql_3_key') ); }

}}

The deleteByTag method should also be able to compare the tag against regular expression...

Comment by Jonathan H. Wage [ 18/Oct/09 ]

Please remember we are limited by what the cache drivers can do. We can only store key => value pairs and can only select and delete one key at a time. No deleting by regular expression or anything like that. All your above suggestions are great idealistically but are impossibly to implement so we need to keep that in mind.

Comment by Miloslav "adrive" Kmet [ 19/Oct/09 ]

Jon, have you ever seen the sf*Cache classes?

Please, look at http://trac.symfony-project.org/browser/branches/1.2/lib/cache/sfMemcacheCache.class.php especially on methods set, setCacheInfo, removePattern. I know that the drivers doesn't have functions for regexp searching. Therefor I am suggesting to store also the cache info as symfony does.

I will create some patches in a few days...

Comment by Jonathan H. Wage [ 20/Oct/09 ]

Ok. I understand now. i think we can implement something similar where we just maintain our own list/index of all the keys we've cached so that we can perform regex deletions. I have some patches that I will commit today because I want to release alpha3 asap.

Comment by Jonathan H. Wage [ 20/Oct/09 ]

I committed some changes that now allow you to delete by regular expressions. We need to test this asap so that I can release alpha3 tomorrow morning.





[DC-108] new Doctrine_Expression('NOW()') - now dont work Created: 14/Oct/09  Updated: 14/Oct/09  Resolved: 14/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.1.4
Fix Version/s: 1.0.13, 1.1.5, 1.2.0-ALPHA3

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


 Description   

I always use this counstructions for get mysql current time:

example:
$us = Doctrine::getTable ( "Users" )->find ( 1 );
$us->currentlogin = new Doctrine_Expression('NOW()');
$us->save();

but after update to new version this DONT work!






[DC-105] notnull: false is ignored for integers with the mssql export Created: 14/Oct/09  Updated: 14/Oct/09  Resolved: 14/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.1.4, 1.2.0-ALPHA1, 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Rich Birch Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP Professional SP3, SQL Server Express 2008



 Description   

The following yml schema will result in a table with the integer field marked as not null

MyTable:
columns:
intfield:
type: integer
notnull: false

I have traced this back to line 244 in the getIntegerDeclaration function in lib/Doctrine/DataDict/Mssql.php

$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';

should be

$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : ' NULL';

This fixes the issue for us and hasn't created any problems thus far.






[DC-102] Fix issue with model builder and class prefix files still prefixing table class files Created: 12/Oct/09  Updated: 12/Oct/09  Resolved: 12/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

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





[DC-101] Length of ForeignKey name in constraint parameter Created: 12/Oct/09  Updated: 12/Oct/09  Resolved: 12/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.2.0-ALPHA3
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Bertrand Zuchuat Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

If the name of ForeignKey constraint is too long, the sql insert failed on this.

I tested with this:
ALTER TABLE article_i18n_index ADD CONSTRAINT article_i18n_index_id_article_i18n_id FOREIGN KEY (id) REFERENCES article_i18n(id) ON UPDATE CASCADE ON DELETE CASCADE;

The article_i18n_index_id_article_i18n_id <-- this is too long

MySql 5.086
Doctrine 1.2 (last)






[DC-100] Patch to solve php fatal error bug in Class Table Inheritance code Created: 12/Oct/09  Updated: 12/Oct/09  Resolved: 12/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Inheritance
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Michael van Tellingen Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None
Environment:

php


Attachments: Text File doctrine.1.2alpha2-citr.patch    

 Description   

Although I know the Class Table Inheritance code is unsupported it is somehow working good enough for me to use this feature anyway.

There is however a bug in the code when not defining column values on the parent object, which the attached small patch solves.

Could this be added before the 1.2 release ? Thanks






[DC-99] Formatting Foreign Key contraint with cross databases Created: 11/Oct/09  Updated: 12/Oct/09  Resolved: 12/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.2.0-ALPHA3
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Bertrand Zuchuat Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File foreignkeycontraintname.patch    

 Description   

This patch change the sign . to _ into the name of foreignKey because the name isn't valid with dot in the name.






[DC-98] Generated base class file names get erroneously prefixed Created: 10/Oct/09  Updated: 17/Jul/14  Resolved: 13/Oct/09

Status: Resolved
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Pim Rupert Assignee: Jonathan H. Wage
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Mac OS X 10.6.1 / PHP 5.3.0


Attachments: File Builder.php     File Builder.php    
Issue Links:
Duplicate
is duplicated by DC-1065 http://www.doctrine-project.org/jira/... Open

 Description   

You can set the boolean option 'classPrefixFiles' to false when generating models to prevent the full class name becoming your file name. However, you this option has no effect on generated base classes. So even if you have set 'classPrefixFiles' to false, the generated files with base classes still contain the base class prefix name in their file name.

I suggest having a 'baseClassPrefixFiles' options OR following the 'classPrefixFiles' option for base class file names as well.

This is how the generated file names ended up in my models folder (with 'baseClassPrefix' = 'Base_'; 'classPrefixFiles' = false; 'baseClassesDirectory' = 'Base' and 'baseClassPrefixFiles' = false):

./Base/Base_Monkey.php
./Monkey.php

Should be:

./Base/Monkey.php
./Monkey.php



 Comments   
Comment by Jonathan H. Wage [ 13/Oct/09 ]

This seems to work for me when I test it.

Comment by Kyle Spraggs [ 05/Jan/10 ]

baseClassPrefixFiles does absolutely nothing on v1.2.1. I have patched Doctrine_Import_Builder to provide this functionality.

– ADD around line 132
/**

  • Whether to use the base class prefix for the filenames too
  • @var boolean
    **/
    protected $_baseClassPrefixFiles = true;

– MODIFY around line 1004

  • $baseClass['className'] = $this->_baseClassPrefix . $baseClass['className'];

+ if ($this->_baseClassPrefixFiles)

{ + $baseClass['className'] = $this->_baseClassPrefix . $baseClass['className']; +}
Comment by Kyle Spraggs [ 05/Jan/10 ]

Seems I was a little to hasty. I'm attaching the properly patched file for review.

Comment by Kyle Spraggs [ 05/Jan/10 ]

Adds the option baseClassPrefixFiles (default true) to specify whether or not the base class should include the prefix in the filename.

Comment by BizLogic [ 17/Jul/14 ]

I can confirm that this is still an issue in 1.2.4 – Doctrine does not respect the $this->_baseClassPrefixFiles because this variable does not exist in ./Doctrine/Import/Builder.php. Additionally some logic is missing for determine whether to use the prefix or not.

I have attached the patched file.





[DC-95] support PEAR file/class naming conventions when generating model classes with a base class Created: 09/Oct/09  Updated: 16/Nov/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: New Feature Priority: Major
Reporter: Lukas Kahwe Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

Currently its not possible to generate base classes that are compatible with the PEAR file/class naming conventions
user -> user.php
base_user -> base/user.php

The following settings do not give the desired results
         baseClassPrefix: "base_"
        baseClassesDirectory: "base"

This seems like a very surprising, yet critical omission, which forces a symfony style autoloader instead of the Doctrine native autoloader.



 Comments   
Comment by Andreas Möller [ 16/Nov/09 ]

I got it to work using the following options

baseClassPrefix = "Base_"
baseClassesDirectory =
baseClassName = "Default_Model_Base_Abstract"
classPrefix = "Default_Model_"
classPrefixFiles = FALSE
pearStyle = TRUE

However, I have not been able to generate tables from the models generated.

Comment by Jonathan H. Wage [ 16/Nov/09 ]

Are you using the generateTableClasses = TRUE option?

Comment by Jonathan H. Wage [ 16/Nov/09 ]

Oh sorry, you said "generate tables from the models generated"....Misunderstood, that you meant Table classes. You are using the zend autoloader right?

Comment by Andreas Möller [ 16/Nov/09 ]

Yes, I'm using the Zend autoloader. Or, at least this is what I would like to do, generate model classes that are prefixed by

Default_Model_

and keep working with the models as I have been prior to attempting to use the options

classPrefix = "Default_Model_"
pearStyle = TRUE

At first, I made an attempt with

generateTableClasses = FALSE

but then, switched to

generateTableClasses = TRUE

and then I just turned off the file not found warnings using

Zend_Loader_Autoloader::getInstance()->suppressNotFoundWarnings(TRUE);

although this can't be the cure, I believe.

However, tables were not generated, only after extending

Doctrine_Export

and adjusting

public function exportSchema($directory = null)
    {
        $classPrefix = 'Default_Model_';
        if ($directory !== null) {
            $models = Doctrine_Core::filterInvalidModels(Doctrine_Core::loadModels($directory, NULL, $classPrefix));
        } else {
            $models = Doctrine_Core::getLoadedModels();
        }

        $this->exportClasses($models);
    }

but this resulted in translation (I18n) tables generated as such

content
default__model__content__translation
Comment by Jonathan H. Wage [ 16/Nov/09 ]

The prefix won't allow you to work with things like you did before, without the prefix The prefix is only for generation. You must still type the full name everywhere in your code. Make sure you are doing the following too:

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, Doctrine_Core::MODEL_LOADING_PEAR);

Doctrine_Core::setModelsDirectory('models');




[DC-92] Doctrine_Import_Pgsql::listTableColumns() creates wrong default values for boolean fields Created: 08/Oct/09  Updated: 13/Oct/09  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: 1.0.13, 1.1.5, 1.2.0-ALPHA3

Type: Bug Priority: Critical
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

When importing a db table as a model, we see the following for a boolean field:

        $this->hasColumn('is_blocked', 'boolean', 1, array(
             'type' => 'boolean',
             'length' => 1,
             'fixed' => false,
             'unsigned' => false,
             'notnull' => true,
             'default' => 'false',   // <----- this field not 0, 1 or a boolean, but a string literal linstead
             'primary' => false,
             ));

Creating an object and immediately saving it results in two validation errors for this field:

1. The field is not boolean, but string
2. The field is not length 1, but length 5 (string "false")

I applied the following patch to the listTableColumns() function:

            elseif (preg_match("/^'(.*)'::character varying$/", $description['default'], $matches)) {
                $description['default'] = $matches[1];
            }
+           elseif ($description['type'] == 'boolean') {
+               if ($description['default'] === 'true') {
+                   $description['default'] = true;
+               } elseif ($description['default'] === 'false') {
+                   $description['default'] = false;
+               }
+           }

            $columns[$val['field']] = $description;

This makes the import work as expected for us.






[DC-91] Adjust file structure to make Doctrine more compatible with existing autoloaders via svn:externals Created: 08/Oct/09  Updated: 12/Oct/09  Resolved: 12/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

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


 Description   

The Doctrine.php class makes it very hard to pull in Doctrine via svn:externals in combination with an existing autoloader. The problem is the Doctrine.php this means you usually end up with something like Doctrine/Doctrine.php locally, which means you need to use the Doctrine autoloader or add another include path.

One solution is to simply do two externals:
http://svn.doctrine-project.org/branches/1.2/lib/
http://svn.doctrine-project.org/branches/1.2/lib/Doctrine

And then including Doctrine.php manually.
The issue is of course that I cannot just do an external on the file because those only work on local repos. Svn also does not support sparse checkouts for externals.

I see 2 solutions:
1) Simple solution would be to provide a directory with just Doctrine.php via a separate url
2) Move the code in Doctrine.php to Doctrine/Core.php and just extend that class from Doctrine.php for BC



 Comments   
Comment by Lukas Kahwe [ 11/Oct/09 ]

It might make sense to document inside the ticket what approach you took ..

Comment by Lukas Kahwe [ 12/Oct/09 ]

It seems you forgot to set the ticket ID in your commits. If the following change is the reason for this ticket being marked as "fixed", then it didnt really solve my issue. the issue is simply one of not being able to checkout Doctrine in a way that is compatible with the pear naming convention without having to add Doctrine to the include path. the solution is to either kill Doctrine.php or to at least provide Doctrine.php as an external without any addition subdirectories .. maybe put Doctrine.php into Doctrine/Doctrine/Doctrine.php via an inter repository file only external.

    1. Added Doctrine::setPath()
      128
      129 Now you can specify the path to your Doctrine libraries if Doctrine.php is
      130 outside of the location of your libraries.
      131
      132 So if `Doctrine.php` is located at `/path/to/Doctrine.php` and the actual
      133 libraries are at `/path/to/the/doctrine/libs` you would need to do the
      134 following.
      135
      136 [php]
      137 Doctrine::setPath('/path/to/the/doctrine/libs');




[DC-90] Proposal: add Doctrine_Record::setColumnOption() method (diff included) Created: 08/Oct/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Record
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Major
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: File setColumnOption.diff    
Issue Links:
Reference
relates to DC-63 Option to additionally add validators... Closed

 Description   

We are generating our entity classes from the database. By doing so, we get a nicely separated set of base record classes and derived record classes where we can implement our logic. The case is, that we want to add validators to about every field there is. The only way that we can do that right now, is by overriding the setUp() method, calling parent::setUp() and providing new column definitions using addColumn(). By doing so, we do have to include the options that were so nicely automatically determined from the database. If we now update our schema in the db and regenerate the base record classes, we might have to manually update addColumn() calls in derived records.

To make it possible to fully separate the automatic and manual code, we were looking for a method to tweak an already existing table, but we couldn't find such method. Therefore, we implemented one ourselves.

A practial usage example. This is what we had to write in the derived class (not a validator example, but the idea is the same of course: tweak or add a column option):

    // Override the "info" column definition. We want this field to be
    // an object field, so we can store a serialized object in it.
    $this->hasColumn('info', 'object', null, array(
      'type' => 'object',
      'fixed' => false,
      'unsigned' => false,
      'notnull' => true,
      'primary' => false,
    ));

This is what we write now:

    $this->setColumnOption('info', 'type', 'object');

Please, consider adding the proposed change from the attached diff file. Of course, also let me know if there is a better way to handle this.



 Comments   
Comment by Maurice Makaay [ 08/Oct/09 ]

Diff for adding a setColumnOption() method to Doctrine_Record.

Comment by Maurice Makaay [ 08/Oct/09 ]

A collegue added another method for batch-setting options in an easy way. It would be nice if this one could also be added.

    /**
     * setColumnOptions
     * sets options for existing column definitions
     *
     * @param array $options          array of arrays with
     *                                ($name, $option, $value) combinations
     */
    public function setColumnOptions($options) {
      foreach($options as $optionset)
      {
        $this->_table->setColumnOption($optionset[0], $optionset[1], $optionset[2]);
      }
    }

Example end-product code:

class Address extends BaseAddress
{
  public function setTableDefinition()
  {
    parent::setTableDefinition();
    $this->setColumnOptions(array(
      array('kind_of_address', 'Yoda_Doctrine_Validator_StringLength', array(3, 10)),
      array('street', 'Yoda_Doctrine_Validator_StringLength', array(3, 45)),
      array('street_short', 'Yoda_Doctrine_Validator_StringLength', array(3, 24)),
      array('housenumber', 'Yoda_Doctrine_Validator_Housenumber', true),
      array('housenumber_extension', 'Yoda_Doctrine_Validator_StringLength', array(0, 25)),
      array('postcode', 'Yoda_Doctrine_Validator_StringLength', array(3, 6)),
      array('postcode', 'Yoda_Doctrine_Validator_Postcode', true),
      array('city', 'Yoda_Doctrine_Validator_StringLength', array(3, 24)),
      array('province', 'Yoda_Doctrine_Validator_StringLength', array(3, 25)),
      array('country', 'Yoda_Doctrine_Validator_StringLength', array(3, 25)),
      array('status',  'Yoda_Doctrine_Validator_StringLength', array(3, 30)),
    ));
  }
}




[DC-89] Doctrine_Table::setColumn() "... as ..." parsing code typo. Created: 08/Oct/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Record
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: 1.0.13, 1.1.5, 1.2.0-ALPHA3

Type: Bug Priority: Trivial
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

From the setColumn() function in Doctrine_Table:

        // extract column name & field name
        if (stripos($name, ' as '))
        {
            if (strpos($name, ' as')) {
                $parts = explode(' as ', $name);
            } else {
                $parts = explode(' AS ', $name);
            }

Because strpos($name, ' as') is missing a space after "as", there is a (I admin, quite rare case that this might fail, namely a case like "ArchiveStatus AS as". This would match the case sensitive ' as' check and it would then split on ' as ', resulting in breakage.






[DC-86] NOW() doesn't work in Sqlite driver Created: 07/Oct/09  Updated: 13/Oct/09  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Connection
Affects Version/s: 1.1.4
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Jacek Dębowczyk Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

sqlite


Attachments: Text File DC86.patch     File DC86TestCase.php    

 Description   

The problem is concerned about sqlite driver. Currently in every occurence of "NOW()" in where clause PDO substitutes result of PHP time() function. Here is a cause:

            $this->dbh->sqliteCreateFunction('now', 'time', 0);

Unfortunatelly, sqlite expects a datetime value rather then integer timestamp.

In result, every occurence of 'now()' in where clause is treated as '0'.

I have prepared a testcase and patch.






[DC-84] Migration automation methods break with tables and fks on the same migration class Created: 06/Oct/09  Updated: 13/Oct/09  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Migrations
Affects Version/s: 1.2.0-ALPHA2
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Ariel Arjona Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello,

Currently if within a single migration class one uses the automation methods $this->table() and $this->foreignKey() the process will fail when moving down because the system will execute the down direction in the same order as the up direction. For example:

public function migrate($direction) {
$this->table($direction, 'mytable', ...);
$this->table($direction, 'myrelatedtable', ... );
$this->foreignKey($direction, 'mytable', 'myfkname', ...);
}

Going up, everything is fine. The tables are created and the FK is applied. Going down, however will error out since by the time the FK is going to be removed the table it belons to is gone.



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

Hmm. Would this fix the problem? I am unsure if this would cause any other problems.

Index: lib/Doctrine/Migration.php
===================================================================
--- lib/Doctrine/Migration.php	(revision 6437)
+++ lib/Doctrine/Migration.php	(working copy)
@@ -499,6 +499,9 @@
 
             if ($migration->getNumChanges() > 0) {
                 $changes = $migration->getChanges();
+                if ($direction == 'down') {
+                    $changes = array_reverse($changes);
+                }
                 foreach ($changes as $value) {
                     list($type, $change) = $value;
                     $funcName = 'process' . Doctrine_Inflector::classify($type);
Comment by Ariel Arjona [ 07/Oct/09 ]

That would work but it would have to check if there's a migrate() method otherwise it would reverse regular down() methods:

if ($direction == 'down' && method_exists($migration, 'migrate'))





[DC-82] Conditional unique validator and index Created: 06/Oct/09  Updated: 05/Nov/14  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.1.4
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Major
Reporter: Jacek Dębowczyk Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File conditional_unique.patch    
Issue Links:
Reference
is referenced by DDC-3117 [GH-1027] Support for Partial Indexes... Resolved

 Description   

Doctrine currently doesn't support conditional unique keys. One commonly happening situation is when we have a model with a column (eg. named "deleted") indicates whether the record was deleted and should no longer be treated as active. If we have an unique index on a "name" column, the index should contain only records with deleted = false. It also concerns an unique validation.

I have prepared a patch for Doctrine_Validator_Unique and Doctrine_Export_Pgsql (Postgresql natively supports conditional indexes).

Example of usage:

public function setTableDefinition()
{
  $this->hasColumn('id', 'integer', 4, array('primary' => true, 'autoincrement' => true, 'sequence' => 'model_id_seq'));
  $this->hasColumn('name', 'string', 128, array('notnull', 'unique' => array('where' => 'deleted = false')));
  $this->hasColumn('deleted', 'boolean', 1, array('notnull', 'default' => false));
  $this->index('model_unique_name', array('fields' => array('name'), 'where' => 'deleted = false', 'type' => 'unique' ));
}





[DC-79] Unexpected exception type when saving a relation with an invalid model in it Created: 04/Oct/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Connection, Record, Relations, Validators
Affects Version/s: 1.1.4, 1.2.0-ALPHA1
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Maurice Makaay Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu Linux, PostgreSQL 8.3, PHP 5.2.6


Attachments: File test.php     File test.yml    

 Description   

When creating two related models and saving the main one to the database, both models get stored in the database. That is expected behavior. Now, when one of the two models has a validation problem and I call save() on it - without first linking it to the other model - I get a Doctrine_Validator_Exception. That is expected behavior. Now (patience, we're getting to the bug now), when one or both of the models has a validation problem and I link them prior to saving them, I don't get a Doctrine_Validator_Exception, but instead a database level exception Doctrine_Connection_Pgsql_Exception. That is unexpected behavior.

One wouldn't notice this issue when doing code like:

  try {
    $object->save();
  } catch (Exception $e) {
    // .. handle the exception
  }

However, code like we are using it in our project more often looks like this:

  try {
    $object->save();
  } catch (Doctrine_Validator_Exception $e) {
    // .. handle the validation exception
  } catch (One_Of_Our_Exception $e) {
    // .. handle our exception
  } catch (Exception $e) {
    throw $e; // unexpected exception, re-throw and pray 
  }

In the attachment you find a test.yml and a test.php that I used for figuring out the behavior. Here's the output from running the test script:

1. OK, got expected exception
2. OK, record A saved
3. OK, got expected exception
4. OK, record B saved
5. OK, record A saved with a linked record B
6. Error: unexpected exception was thrown.
   Type: Doctrine_Connection_Pgsql_Exception
   Message: SQLSTATE[23502]: Not null violation: 7 ERROR:  null value in column "b_id" violates not-null constraint
7. Error: unexpected exception was thrown.
   Type: Doctrine_Connection_Pgsql_Exception
   Message: SQLSTATE[23502]: Not null violation: 7 ERROR:  null value in column "a_id" violates not-null constraint
8. Error: unexpected exception was thrown.
   Type: Doctrine_Connection_Pgsql_Exception
   Message: SQLSTATE[23502]: Not null violation: 7 ERROR:  null value in column "a_id" violates not-null constraint

Inspecting the Connection/UnitOfWork.php code, I see that saveGraph() calls $isValid = $this->insert($record). Now, when insert() sees that the record is invalid, it returns a false value. Somewhat later this results in calling $conn->transaction->addInvalid($record) to register the problem. At the end of the code block, I find (around line 126):

                // save the MANY-TO-MANY associations
                $this->saveAssociations($record);

That is the point where things break. Even when an associated record does not validate, saveAssociations() will be called, resulting in a db level error about a reference id not being set (logical, since the related record was not saved and did not get an id assigned to it).

In my opinion, this shouldn't happen, but I'm only using Doctrine for one day, so if I am missing some important piece of knowledge or documentation here, then please let me know.



 Comments   
Comment by Maurice Makaay [ 04/Oct/09 ]

Note: I have tested some more and like expected, I got the correct exception when loading an existing A->B relation, breaking B and calling A->save(). In that case, storing the AB relation won't fail, because B already has an id. Saving the relation is successful and in the end, the validation exception is thrown as expected.

Test code for this extra test case:

$at = Doctrine::getTable('A');
$a = $at->find(1); 

$a->Bs[0]->field = null;

$a->save();




[DC-78] Doctrine_Cli: tests and refactorings Created: 04/Oct/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Cli
Affects Version/s: 1.1.4
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Minor
Reporter: Dan Bettles Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

Darwin, PHP 5.3, MacBook


Attachments: File cli_tests_and_refactorings.diff    

 Description   

I'm a fan of the CLI and tasks in Doctrine, but I recently had some trouble registering custom tasks.

Having spent a good while refactoring this weekend, I understand that you can load additional tasks from a particular directory. Unfortunately, the tasks in said directory must follow the Doctrine naming conventions (i.e. they must start "Doctrine_Task").

I'm using Doctrine 1.1.4 on PHP 5.3 and am using namespaces. Ideally, then, I don't want to have to follow the Doctrine naming conventions: I want to be able to use my own.

Here's an example of what I can now do with my patched version:

$cli = new Doctrine_Cli($config);
$cli->registerTask('sakura\installer\doctrine\GenerateModelsDb', 'sakura-generate-models-db');
$cli->run($_SERVER['argv']);

I have also implemented a public loadAndRegisterTask() method that will load a specified file and then register a class.

In refactoring Doctrine_Cli, I've written a test case, Doctrine_Cli_TestCase, which reasonably thoroughly tests the new and some of the old functionality. There's still scope for some more refactoring and testing, but I've got what I need for now.

The enclosed patch was created against the 1.1.4 tag.

Best regards






[DC-76] [PATCH] The interface Doctrine_Record_Listener_Interface does not define all the required methods to create custom listeners. Created: 01/Oct/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Marijn Huizendveld Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

within sfDoctrinePlugin


Attachments: File patch_doctrine_record_listener_interface.diff    

 Description   

The Doctrine_Record_Listener_Interface is no longer up to date with the code base. The code base expects the listener to implement a getOption method which is not available on my listener models... See the patch file.



 Comments   
Comment by Marijn Huizendveld [ 01/Oct/09 ]

I've taken the liberty to remove the `public` keyword from the `interface` definition which seemed a bit redundant given the fact that it is an interface... Sorry for that :-$





[DC-71] classPrefixFiles should affect base classes as well Created: 30/Sep/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Import/Export
Affects Version/s: 1.2.0-ALPHA1
Fix Version/s: 1.2.0-ALPHA3

Type: Improvement Priority: Minor
Reporter: Glen Ainscow Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None


 Description   

... or there should be a "baseClassPrefixFiles" option.

I've set the priority of this ticket to minor, but I'd really like this to be implemented so that I don't have to rename files after generating them.



 Comments   
Comment by Glen Ainscow [ 01/Oct/09 ]

Actually, this isn't really what I need. It would work, but it'd be like:

/models
      /generated
            User.php               (Blog_Model_Base_User)
      User.php                     (Blog_Model_User)

I'd prefer it if the generated model file was named BaseUser.php.

See http://www.nabble.com/Autoloading-Doctrine-models-base-models-td25687101.html

Comment by Jonathan H. Wage [ 09/Oct/09 ]

I really don't understand what you mean you need to be more descriptive of what you want it to do.

Comment by Jonathan H. Wage [ 09/Oct/09 ]

I fixed this in 1.2. I think it does what you want now. It was related to this ticket

http://www.doctrine-project.org/jira/browse/DC-95

Comment by Glen Ainscow [ 09/Oct/09 ]

Sorry for not being clear. I wanted something like this:

File Name            Class Prefix        Base Prefix         Model Name
----------------------------------------------------------------------
Post.php             Blog_Model_                             Post        (Blog_Model_Post)
BasePost.php         Blog_BaseModel_     Base                Post        (Blog_BaseModel_BasePost)

... but it's not possible to set a different class prefix for base models. However, I actually think "Blog_Model_BasePost" might be better, and Doctrine does support this. The Zend Framework resource autoloader doesn't though, so I've submitted an issue report there.

Thanks.





[DC-68] When exporting model to SQL, Doctrine generates erroneous constraint name for table name with schema Created: 28/Sep/09  Updated: 13/Oct/09  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Connection, Import/Export, Relations
Affects Version/s: 1.1.4
Fix Version/s: 1.2.0-ALPHA3

Type: Bug Priority: Major
Reporter: Jacek Dębowczyk Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None
Environment:

pgsql


Attachments: File DC68TestCase.php     File Doctrine_Connection.diff    

 Description   

For example, for a foreign key from user.group_id -> group.id in a schema "main" - with explicite specified the schema name in the table names (main.user, main.group) - Doctrine generates a constraint name "main.user_group_id_main.group_id". Unfortunately, "." is reserved char and is illegal in a constraint name.



 Comments   
Comment by Jacek Dębowczyk [ 28/Sep/09 ]

TestCase

Comment by Jacek Dębowczyk [ 28/Sep/09 ]

Patch





[DC-64] Sluggable extension: new provider option for custom unique slugs Created: 25/Sep/09  Updated: 13/Oct/09  Resolved: 13/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Sluggable
Affects Version/s: None
Fix Version/s: 1.2.0-ALPHA3

Type: New Feature Priority: Minor
Reporter: Maik Riechert Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File sluggable.patch     Text File sluggable_listener.patch    

 Description   

Recently I had a model where I needed a custom unique slug instead of a slug which is built from fields.

At first I thought that maybe the "builder"-option was there for that purpose but soon I realized that this is obviously not the right one.

The only left option was that I would need to create the method "getUniqueSlug" in the record class. This is of course an option and has its uses but with it you would have to reimplement the collision detection for uniqueness again which are already implemented in the getUniqueSlug-method of the sluggable class.

After reading the code several hours I came to the conclusion that this functionality is simply missing so I created a new option called "provider" which is a callback. This callback provides the equivalent of the concatenation of the table fields. The great thing about this is that you don't have to care for uniqueness or the proper urlized format because this is still taken care of by the sluggable behaviour. Thus this patch is very unobtrusive and completely backwards-compatible of course.

Usage is pretty straight-forward:

model:
  actAs:
    Sluggable:
      provider: [modelTable, provideSlug]

Or whatever you want to name the method which is called.

jwage responded in trac:

This is already possible if you just implement a toString() method and don't specify any fields.

But I have to disagree. If I use toString() I still have to care about the uniqueness of the slug by myself because only when fields are specified this gets called inside the code:

$this->getUniqueSlug($record, $value);

Otherwise only the builder-function is called.

So atm this is NOT possible.



 Comments   
Comment by Jonathan H. Wage [ 25/Sep/09 ]

Ah Ok. I think maybe we could make some change to always run the slug through the function to ensure uniqueness and proper format. We could try that.

Comment by Maik Riechert [ 25/Sep/09 ]

If I might say this I think that the behaviour of the sluggable template is highly incomprehensible if you don't use the standard function with simple fields. It looks like a bit of patchwork to me.

The first thing I don't quite understand is that why is there an option to disable uniqueness? Isn't a slug by itself supposed to be always unique? What other uses could a slug have if it isn't?

Second, I don't think that "$value = (string) $record;" should be anywhere used for real logic. The toString() method is actually there for debugging purposes but not for providing slugs or anything else.

If you want to change it then really change it but not by doing a "$this->getUniqueSlug(..)" around the "(string) $record". I know that backwards compatibility is important. That is why I thought about a very unobtrusive way. Maybe if you look at the patch a second time you're starting to like it more

Comment by Jonathan H. Wage [ 13/Oct/09 ]

Fixed by r6496 in Doctrine 1.2

Comment by Maik Riechert [ 13/Oct/09 ]

Thanks for implementing it. Although I don't use this possibility I think you broke backwards-compatibility which I wanted to avoid, notably for the getUniqueSlug-way because in the past this was the way for caring about the uniqueness on ones own, and now you make it unique again by doing the "if ($this->_options['unique'] === true)

{" check for every way. This probably won't make a difference because it's unique in the first place but the point of having this "}

else if (method_exists($record, 'getUniqueSlug')) {" was that one could save the effort that doctrine itself would have made which are also db queries. So effectively you lowered the performance of Sluggable in some cases

Comment by Maik Riechert [ 13/Oct/09 ]

I have to correct myself. Of course you didn't break backwards compatibility with the getUniqueSlug-way, this will be only slower. The one where you broke it is where it gets the slug with "$value = (string) $record;" but this is indeed the right way to go because no one would suspect that a __toString method should care about uniqueness.

My suggestion:

Instead of

if ($this->_options['unique'] === true)

{ return $this->getUniqueSlug($record, $value); }

do

if ($this->_options['unique'] === true && !method_exists($record, 'getUniqueSlug')) { return $this->getUniqueSlug($record, $value); }

This should also make it quite clear to see that Sluggable always handles uniqueness if it's requested but for the getUniqueSlug-way. Maybe you should put the method_exists() in a variable to not have it called twice.





[DC-63] Option to additionally add validators to fields Created: 25/Sep/09  Updated: 09/Oct/09  Resolved: 09/Oct/09

Status: Closed
Project: Doctrine 1
Component/s: Validators
Affects Version/s: None
Fix Version/s: 1.2.0-ALPHA3

Type: New Feature Priority: Minor
Reporter: Erol Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File validators.txt    
Issue Links:
Reference
is referenced by DC-90 Proposal: add Doctrine_Record::setCol... Closed

 Description   

If we follow the logic that Base models are auto generated and we extend in improve them in our "main" models, then its also necessary to control validators. We shouldnt not manually specify them in Base models, so there should be a way to control them.

I have written a simple function which sets validators for field/fields.






Generated at Fri Dec 19 00:34:59 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.