GithubHelp home page GithubHelp logo

doctrine / orm Goto Github PK

View Code? Open in Web Editor NEW
9.9K 253.0 2.5K 51.44 MB

Doctrine Object Relational Mapper (ORM)

Home Page: https://www.doctrine-project.org/projects/orm.html

License: MIT License

PHP 99.99% Shell 0.01%
hacktoberfest

orm's Introduction

4.0.x 3.3.x 3.2.x 2.20.x 2.19.x
Build status Build status Build status Build status Build status
Coverage Status Coverage Status Coverage Status Coverage Status Coverage Status

πŸ‡ΊπŸ‡¦ UKRAINE NEEDS YOUR HELP NOW!

Doctrine ORM is an object-relational mapper for PHP 8.1+ that provides transparent persistence for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), inspired by Hibernate's HQL. This provides developers with a powerful alternative to SQL that maintains flexibility without requiring unnecessary code duplication.

More resources:

orm's People

Contributors

alcaeus avatar asm89 avatar bakura10 avatar beberlei avatar benmorel avatar deeky666 avatar derrabus avatar fabiobatsilva avatar goetas avatar greg0ire avatar guilhermeblanco avatar jean85 avatar jwage avatar lcobucci avatar majkl578 avatar mnapoli avatar morozov avatar mpdude avatar nicolas-grekas avatar ocramius avatar phansys avatar reenexe avatar romanb avatar schmittjoh avatar senseexception avatar shurakai avatar simpod avatar stof avatar thomaslandauer avatar vincentlanglet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orm's Issues

DDC-9: Add support to "options" in XML Mapping Driver

Jira issue originally created by user romanb:

Currently users can't define configurable options for their custom types. To support a configurable approach, we should inject an options items that holds configuration data.

Here is the suggested approach:

<field name="..." type="mytype">
    <options>
        <option name="xxx" value="xxx"/> 
        ...
    </options>
    ... 
</field>

I already updated YAML and Annotations drivers to support it. XML is a little more complicated and required some changes in XSD file.

DDC-38: associations that are null should not create a prox object

Jira issue originally created by user itoijala:

Associations that are nullable do not work as expected. When the association is null, i.e. the id in the database is null, the association is not null when loaded from the database. Doctrine creates a proxy object for the association that, when loaded, has no values for any fields. Doctrine should check during object hydration if the association is null. If true then no proxy object should be created. Please see DDC-34 for my schema.

DDC-17: Ability to skip the operation from a pre-operation event handler

Jira issue originally created by user itoijala:

In Doctrine 1.1 it is possible to skip the operation in the event handlers in Doctrine_Record_Listener using Doctrine_Event::skipOperation.

This no longer seems to be possible in Doctrine 2.0 Alpha 1, for example when handling a preRemove event to implement soft-delete behaviour. Perhaps a method could be added to \Doctrine\Common\EventArgs\LifecycleEventArgs to skip the operation, at least before the operation.

Without this implementing soft-delete would require the user to update deleted_at and deleted_by himself and then save the record. It could no longer be done automatically when removing a record because the record is then removed.

DDC-25: Boolean type does not work

Jira issue originally created by user itoijala:

The boolean type does not work. The method used by BooleanType does not exist. It should probably use getBooleanTypedeclarationSql(array $field).

In Doctrine\DBAL\Types\BooleanType:

OLD:
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getBooleanDeclarationSql();
}

NEW:
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getBooleanTypeDeclarationSql($fieldDeclaration);
}

DDC-30: DateTimeType should take into account null as a possible value

Jira issue originally created by user itoijala:

DateTimeType does not expect the value to be null, both conversions ignore this possibility. This bug is especially annoying when converting from the database to PHP. The user does not expect to get false as a value for a datetime field. False is returned by DateTime when null is given. Null should be returned as the PHP value. Converting to the database from PHP would result in an error, since $value would be null.

Simple fix:

OLD:

public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
    return $value->format($platform->getDateTimeFormatString());
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
    return \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
    }

NEW:

public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if ($value !== null)
        {
            return $value->format($platform->getDateTimeFormatString());
        }
        else
        {
            return null;
        }
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        if ($value !== null)
        {
            return \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
        }
        else
        {
            return null;
        }
    }

DDC-2: Proxies in UoW::_computeChangeSets

Jira issue originally created by user romanb:

When having a proxy object, say "PhonenumberProxy? extends Phonenumber", and its not yet loaded from the database I think an error occures in the UnitOfWork::_computeChangeSets function since it goes and retrieves that lazy load object value using an instance of "ReflectionProperty?". However with it being lazily loaded the value must be null.

DDC-45: Consider changing the contract of Collection#remove

Jira issue originally created by user romanb:

The current contract of Collection#remove requires the collection to be initialized/loaded. This can be quite inefficient. It needs to be investigated whether this contract can be changed so that initialization of the collection is not necessary, similar to Collection#add.

DDC-18: Track proxy objects in the identity map?

Jira issue originally created by user romanb:

Proxy objects may need to be tracked in the identity map in order to prevent the possibility of having several proxy objects for the same entity.

DDC-12: Enhance "Working with objects" chapter

Jira issue originally created by user romanb:

That chapter still needs the "Transitive Persistence" section to be written and it also needs sections about working with associations (single-valued and collections).

DDC-3: Support for CASE expressions in DQL

Jira issue originally created by user romanb:

CASE expressions should be supported in DQL similarly to the definition found in 4.6.17.3 of the JPA 2.0 specification.

Steps: 1) Adjust the BNF
2) Adjust the Parser according to the changed BNF
3) Adjust the SqlWalker? to produce the correct SQL

DDC-22: EntityManager#refresh() should also refresh associations.

Jira issue originally created by user romanb:

Initially this issue was brought up by DC-41 which in turn led to DDC-21. The implementation of DDC-21 requires a working refresh() implementation that also refreshes associations.

  1. For the state of the entity that is refreshed itself this is self-explanatory (simple select on the primary table, this is what already works).

  2. For single-valued associations the proper query depends on whether the entity being refreshed represents the owning side or the inverse side of the association. If it is the inverse side, a simple query like this should do:

select addresses.id, ... from addresses where addresses.user_id=?

If it is the owning side, a join may be required:

select addresses.id, ... from addresses inner join users on addresses.id = users.address_id where users.id=?
  1. For one-to-many collections, a simple select on the target entity table, similar to the following should do:
select .... from phonenumbers ... where phonenumbers.user_id=?

For many-to-many collections a similar select that joins over the join table is required.

An clever way for collections might be to not trigger this SQL immediately on refresh() but to simply mark the collection as uninitialized again so that the first access would trigger the reload, similar to a lazy-load.

Note that the collection itself is refreshed, not the state of the entities contained therein.
Also note that only associations need to be refreshed that were already initialized. If an associated collection is uninitialized, it does not need to be refreshed. If an associated single-valued proxy is uninitialized, it does not need to be refreshed.

DDC-35: [patch] The cli configuration maps the convert-mapping task to the wrong file name for the class

Jira issue originally created by user marijn:

Currently the Cli class maps the convert-mapping task to the class with file name MappingTask but this should be ConvertMappingTask since that is the name of the class. I've attached -two patch files- (svn diff doesn't add the renamed file) one patch file. The first one renames the name of the class. -The second one renames the file to ConvertMappingTask-.

DDC-8: DQL Join fails when primary key is not called "id"

Jira issue originally created by user ablock:

A class A has a bidirectional onetomany assocation with a class B. The primary key for A is called "a_id" and is defined like this:

   /****
     * @Id @Column(name="a_id", type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

issuing the command ./doctrine run-dql --dql="select a from Domain3\A a join a.b b where b.id = 1" gives the following error:

PHP Notice: Undefined index: id in /home/ablock/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php on line 657

Notice: Undefined index: id in /home/ablock/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php on line 657
PHP Notice: Undefined index: in /home/ablock/doctrine/lib/Doctrine/ORM/Mapping/ClassMetadata.php on line 1821

Notice: Undefined index: in /home/ablock/doctrine/lib/Doctrine/ORM/Mapping/ClassMetadata.php on line 1821
RunDql:exception 'PDOException' with message '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 'WHERE b1_.id = 1' at line 1' in /home/ablock/doctrine/lib/Doctrine/DBAL/Connection.php:602
Stack trace:
#0 /home/ablock/doctrine/lib/Doctrine/DBAL/Connection.php(602): PDO->query('SELECT a0_.a_id...')
#1 /home/ablock/doctrine/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php(42): Doctrine\DBAL\Connection->execute('SELECT a0_.a_id...', Array)
#2 /home/ablock/doctrine/lib/Doctrine/ORM/Query.php(198): Doctrine\ORM\Query\Exec\SingleSelectExecutor->execute(Object(Doctrine\DBAL\Connection), Array)
#3 /home/ablock/doctrine/lib/Doctrine/ORM/AbstractQuery.php(461): Doctrine\ORM\Query->_doExecute(Array)
#4 /home/ablock/doctrine/lib/Doctrine/ORM/AbstractQuery.php(312): Doctrine\ORM\AbstractQuery->execute(Array, 1)
#5 /home/ablock/doctrine/lib/Doctrine/ORM/Tools/Cli/Tasks/RunDqlTask.php(105): Doctrine\ORM\AbstractQuery->getResult()
#6 /home/ablock/doctrine/lib/Doctrine/ORM/Tools/Cli.php(177): Doctrine\ORM\Tools\Cli\Tasks\RunDqlTask->run()
#7 /home/ablock/doctrine/tools/sandbox/doctrine.php(9): Doctrine\ORM\Tools\Cli->run(Array)
#8 /home/ablock/doctrine/tools/sandbox/doctrine(4): include('/home/ablock/do...')
#9 {main}

If I change the declaration to

/****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

It works

DDC-5: Remove unsigned/fixed

Jira issue originally created by user romanb:

Changeset 6348 introduced unsigned/fixed properties for column metadata. Unsigned is completely unportable and fixed is unnecessary (we could simply introduce a fixed string type for this).

These 2 properties need to be removed.

DDC-42: the DQL parser does not support boolean literal values

Jira issue originally created by user itoijala:

The parser does not support boolean literal values. This means that comparisons like e.unlocked = true result in a syntax error. This is not what is intended, since both documentation and comments in the code Doctrine\ORM\Query\Parser.php line 1870 say that boolean literals are supported.

I have a possible fix. I don't know if it is the best way to fix this.

OLD:

/****
     * Literal ::= string | char | integer | float | boolean
     *
     * @return string
     */
    public function Literal()
    {
        switch ($this->_lexer->lookahead['type']) {
            case Lexer::T_STRING:
            case Lexer::T_INTEGER:
            case Lexer::T_FLOAT:
                $this->match($this->_lexer->lookahead['value']);
                return $this->_lexer->token['value'];
            default:
                $this->syntaxError('Literal');
        }
    }

NEW:

/****
     * Literal ::= string | char | integer | float | boolean
     *
     * @return string
     */
    public function Literal()
    {
        switch ($this->_lexer->lookahead['type']) {
            case Lexer::T_STRING:
            case Lexer::T_INTEGER:
            case Lexer::T_FLOAT:
                $this->match($this->_lexer->lookahead['value']);
                return $this->_lexer->token['value'];
            case Lexer::T_TRUE:
            case Lexer::T_FALSE:
                $this->match($this->_lexer->lookahead['value']);
                return $this->*em->getConnection()->getDatabasePlatform()->convertBooleans(strtolower($this->*lexer->token['value']) == 'true' ? true : false);
            default:
                $this->syntaxError('Literal');
        }
    }

Using convertBooleans is important. Otherwise the sql will have 'true' or 'false'.

Cases T_TRUE and T_FALSE should also be added to ArithmeticPrimary(). (line 2048)

DDC-28: ProxyClassGenerator should not attempt to override static methods

Jira issue originally created by user itoijala:

ProxyClassGenerator overrides all of the methods of the entity class. This includes static methods. If the entity class has a static method, an error occurs:

Fatal error: Cannot make static method Model\User\User::getCurrentUser() non static in class Doctrine\Generated\Proxies\Model_User_UserAProxy in C:\Windows\Temp\Model_User_UserAProxy.g.php on line 200

ProxyClassGenerator should ignore static methods. They do not need to be overriden, since they do not require the entity to be loaded.

A simple fix is to change the line 143 from:

if ($method->isPublic() && ! $method->isFinal()) {

to:

if ($method->isPublic() && ! $method->isFinal() && !$method->isStatic()) {

DDC-24: text type not portable (works only on MySQL)

Jira issue originally created by user itoijala:

The text type is not portable to other RDBMS than MySQL. To support the text type, a platform must implement the method getClobDeclarationSql(array $field). Currently only MySqlPlatform has this method. This means that attempting to use the CLI tool to create a schema with a text column using another RDBMS fails with the following error:

Fatal error: Call to undefined method Doctrine\DBAL\Platforms\SqlitePlatform::getClobDeclarationSql() in D:\Projects\Test\tools\sandbox\lib\Doctrine\DBAL\Types\TextType.php on line 15

I believe at least Sqlite supports the CLOB type.

Either the text type should be supported by all platforms or the documentation should be revised. Currently it says:

"All Doctrine Mapping Types that ship with Doctrine are fully portable between different RDBMS."

This makes easy testing of models using sqlite with minimum configuration impossible with the text type.

DDC-6: Dont use 'length' metadata attribute for anything other than string types.

Jira issue originally created by user romanb:

Changeset 6348 seems to make use of the 'length' attribute for decimals. This is very confusing and was not intended. As mentioned in several places 'length' should only apply to string-valued columns and indicate the desired (maximum) string length.

This is the problematic change:

OLD: ? 10 : $columnDef['precision'];
NEW: ? (( ! isset($columnDef['length']) ](| empty($columnDef['length'))) ? 10 : $columnDef['length']) : $columnDef['precision'];

Needs to be reverted to OLD.

DDC-23: Limit and offset in QueryBuilder

Jira issue originally created by user itoijala:

Currently (2.0 Alpha 1) QueryBuilder does not support limit or offset functionality. These were supported in Doctrine 1 and should be added. QueryBuilder's value is significantly lower without these features because simple pagination is not possible. Methods limit($limit) and offset($offset) should be added to QueryBuilder, like in Doctrine 1. Query already has support for limit and offset, so this should not be a large change.

DDC-11: Complete configuration chapter

Jira issue originally created by user romanb:

The configuration chapter needs to be completed, explaining all the configuration options that are not yet documented.

DDC-31: ClassMetadata discriminatorColumn['name'] should always be set when discriminatorColumn is not null

Jira issue originally created by user itoijala:

When creating an entity, StandardEntityPersister checks if the discriminatorColumn is null. If not it checks if discriminatorColumn['name'] is $column. Sometimes (not sure when), discriminatorColumn['name'] is not set. warning is then emitted:

Notice: Undefined index: name in D:\Projects\NewStein\library\Doctrine\ORM\Persisters\StandardEntityPersister.php on line 504

ClassMetadata should ensure that discriminatorColumn['name'] is always set.

Fix:

OLD (ClassMetadata.php, line 1567):

public function setDiscriminatorColumn($columnDef)
    {
        $this->discriminatorColumn = $columnDef;
        if ( ! isset($columnDef['fieldName'])) {
            $this->discriminatorColumn['fieldName'] = $columnDef['name'];
        }
    }

NEW:

public function setDiscriminatorColumn($columnDef)
    {
        $this->discriminatorColumn = $columnDef;
        if ( ! isset($columnDef['fieldName'])) {
            $this->discriminatorColumn['fieldName'] = $columnDef['name'];
        }
    if (!isset($columnDef['name']))
    {
        $this->discriminatorColumn['name'] = $this->discriminatorColumn['fieldName'];
    }
    }

DDC-27: schema-tool --create creates a table for a mapped superclass

Jira issue originally created by user itoijala:

Using the schema-tool to create the database creates a table for a mapped superclass. I think this behaviour is not desired, since the fields of the superclass also exist in the subclass tables. Running php doctrine schema-tool --create --dump-sql --classdir="<...>" generates the following output (MySql):

CREATE TABLE Blameable (date_created DATETIME NOT NULL, date_updated DATETIME DEFAULT NULL,
date_deleted DATETIME DEFAULT NULL, creator_id INT DEFAULT NULL, updater_id INT DEFAULT NULL,
deleter_id INT DEFAULT NULL) ENGINE = InnoDB
ALTER TABLE Blameable ADD FOREIGN KEY (creator_id) REFERENCES user_users(id)
ALTER TABLE Blameable ADD FOREIGN KEY (updater_id) REFERENCES user_users(id)
ALTER TABLE Blameable ADD FOREIGN KEY (deleter_id) REFERENCES user_users(id)

Only the mapped superclass exists in the classdir. I think it should not create any tables.

DDC-29: ProxyClassGenerator does not correctly override methods with type-hinted array or default values or pass by reference

Jira issue originally created by user itoijala:

The ProxyClassGenerator does not take into account array type-hinting, default values or pass by reference.

Example:

public function exampleMethod(array $array, &$c, $a = 'foo', array $b = array('b'))
{
    /** ... **/
}

Creates the follwing code:

public function exampleMethod($array, $c, $a, $b) 
{
    $this->_load();
    return parent::exampleMethod($array, $c, $a, $b);
}

and the following warning:

Strict Standards: Declaration of Doctrine\Generated\Proxies\Model*User_UserAProxy::exampleMethod() should be compatible with that of Model\User\User::exampleMethod() in C:\Windows\Temp\Model_User*UserAProxy.g.php on line 200

I am not sure about the consequences other than the warning when using E_STRICT.

The fix seems to be relatively simple:

Modify the _generateMethods method in ProxyClassGenerator

OLD:

private function _generateMethods(ClassMetadata $class)
    {
        $methods = '';

        foreach ($class->reflClass->getMethods() as $method) {
            if ($method->isConstructor()) {
                continue;
            }

            if ($method->isPublic() && ! $method->isFinal() && !$method->isStatic()) {
                $methods .= PHP_EOL . 'public function ' . $method->getName() . '(';
                $firstParam = true;
                $parameterString = $argumentString = '';

                foreach ($method->getParameters() as $param) {
                    if ($firstParam) {
                        $firstParam = false;
                    } else {
                        $parameterString .= ', ';
                        $argumentString  .= ', ';
                    }

                    // We need to pick the type hint class too
                    if (($paramClass = $param->getClass()) !== null) {
                        $parameterString .= '\\' . $paramClass->getName() . ' ';
                    }

                    $parameterString .= '$' . $param->getName();
                    $argumentString  .= '$' . $param->getName();
                }

                $methods .= $parameterString . ') {' . PHP_EOL;
                $methods .= '$this->*load();' . PHP*EOL;
                $methods .= 'return parent::' . $method->getName() . '(' . $argumentString . ');';
                $methods .= '}' . PHP_EOL;
            }
        }

        return $methods;
    }

NEW:

private function _generateMethods(ClassMetadata $class)
    {
        $methods = '';

        foreach ($class->reflClass->getMethods() as $method) {
            if ($method->isConstructor()) {
                continue;
            }

            if ($method->isPublic() && ! $method->isFinal() && !$method->isStatic()) {
                $methods .= PHP_EOL . 'public function ' . $method->getName() . '(';
                $firstParam = true;
                $parameterString = $argumentString = '';

                foreach ($method->getParameters() as $param) {
                    if ($firstParam) {
                        $firstParam = false;
                    } else {
                        $parameterString .= ', ';
                        $argumentString  .= ', ';
                    }

                    // We need to pick the type hint class too
                    if (($paramClass = $param->getClass()) !== null) {
                        $parameterString .= '\\' . $paramClass->getName() . ' ';
                    }
                    _* else if ($param->isArray())
                    {
                        $parameterString .= 'array ';
                    } *_

                    _* if ($param->isPassedByReference())
                    {
                        $parameterString .= '&';
                    } *_
                    $parameterString .= '$' . $param->getName();
                    _* if ($param->isDefaultValueAvailable())
                    {
                        $parameterString .= ' = ' . var_export($param->getDefaultValue(), true);
                    } *_
                    $argumentString  .= '$' . $param->getName();
                }

                $methods .= $parameterString . ') {' . PHP_EOL;
                $methods .= '$this->*load();' . PHP*EOL;
                $methods .= 'return parent::' . $method->getName() . '(' . $argumentString . ');';
                $methods .= '}' . PHP_EOL;
            }
        }

        return $methods;
    }

EDIT: forgot to add the fix for pass by reference.
EDIT2: fixed typo.

DDC-13: Enhance DQL chapter

Jira issue originally created by user romanb:

The first half of the chapter "DQL - Doctrine Query Language" needs more examples and detailed explanations about DQL. The explanations need to be understandable and friendly for newcomers with no Doctrine 1.x experience.

DDC-36: EntityManager#persist should accept more objects to easily persist multiple objects.

Jira issue originally created by user marijn:

I think it would be nice if the persist function would accept more objects as an arguments by using func-get-arg see the simple example below:

\


<?php

  $user   = new \Entities\User();
  $person = new \Entities\Person();

  $person->setName('Wage');
  $person->setFirstNames('Jonathan');
  $person->setTitle('mr');

  $user->setPerson($person);
  $user->setPassword('D0ctr1ne');

  $em->persist($person, $user);
  $em->flush();

DDC-10: Complete association-mapping chapter

Jira issue originally created by user romanb:

The chapter about association mapping needs to be filled with the missing content. Many code examples can be taken from the functional ORM test cases.

DDC-34: schema-tool --create tries to create duplicate associations and exits with exception

Jira issue originally created by user itoijala:

I'm getting the error

SchemaTool:Duplicate field mapping ()

when trying to create my database schema. I am pretty sure this worked before. The error occurs on a field defined in a mapped superclass on the first entity that extends this class on the first association.

My entity classes:

namespace Model;

use \Model\User\User;
use \DateTime;

/****
 * @MappedSuperclass
 */
abstract class Blameable
{
    /****
     *
     * @var DateTime
     *
     * @Column(type="datetime", name="date_created")
     */
    protected $dateCreated;

    /****
     *
     * @var User
     *
     * @OneToOne(targetEntity="Model\User\User")
     * @JoinColumn(name="creator_id", referencedColumnName="id", nullable="true")
     */
    protected $creator;

    /****
     *
     * @var DateTime
     *
     * @Column(type="datetime", name="date_updated", nullable="true")
     */
    protected $dateUpdated;

    /****
     *
     * @var User
     *
     * @OneToOne(targetEntity="Model\User\User")
     * @JoinColumn(name="updater_id", referencedColumnName="id", nullable="true")
     */
    protected $updater;

    /****
     *
     * @var DateTime
     *
     * @Column(type="datetime", name="date_deleted", nullable="true")
     */
    protected $dateDeleted;

    /****
     *
     * @var User
     *
     * @OneToOne(targetEntity="Model\User\User")
     * @JoinColumn(name="deleter_id", referencedColumnName="id", nullable="true")
     */
    protected $deleter;
}
namespace Model\User;

use \Zend*Validate*Alnum;
use \Zend*Validate*StringLength;
use \Zend*Validate*Alpha;
use \Zend*Validate*EmailAddress;
use \Zend_Registry;
use \Model\Blameable;
use \Model\ConstraintException;
use \Itoijala_Singletons;
use \Zend_Auth;
use \Itoijala*Password*Hash;

/****
 *
 *
 * @Entity @Table(name="user_users")
 */
class User extends Blameable
{
    /****
     *
     * @var int
     *
     * @Id @Column(type="integer", name="id")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="20", name="username")
     */
    private $username;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="20", name="first_name")
     */
    private $firstName;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="20", name="last_name")
     */
    private $lastName;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="255", name="email")
     */
    private $email;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="20", name="signature")
     */
    private $signature;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="128", name="password")
     */
    private $password;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="255", name="role")
     */
    private $role;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="32", name="session_id", nullable="true")
     */
    private $sessionId;

    /****
     *
     * @var bool
     *
     * @Column(type="boolean", name="unlocked")
     */
    private $unlocked;
}
namespace Model\Article;

use \Closure;
use \Model\Blameable;
use \Doctrine\Common\Collections\Collection;
use \Doctrine\ommon\Collections\ArrayCollection;
use \Model\User\User;
use \Model\Gallery\Gallery;
use \Model\ConstraintException;
use \Zend*Validate*StringLength;

/****
 * @Entity @Table(name="article_articles")
 */
class Article extends Blameable
{
    /****
     *
     * @var int
     *
     * @Id @Column(type="integer", name="id")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
     *
     * @var Category
     *
     * @ManyToOne(targetEntity="Model\Article\Category")
     * @JoinColumn(name="category_id", referencedColumnName="id")
     */
    private $category;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="255", name="name")
     */
    private $name;

    /****
     *
     * @var string
     *
     * @Column(type="text", name="description")
     */
    private $description;

    /****
     *
     * @var string
     *
     * @Column(type="string", length="255", name="thumbnail")
     */
    private $thumbnail;

    /****
     *
     * @var string
     *
     * @Column(type="text", name="content")
     */
    private $content;

    /****
     *
     * @var int
     *
     * @Column(type="integer", name="views")
     */
    private $views;

    /****
     *
     * @var bool
     *
     * @Column(type="boolean", name="news")
     */
    private $news;

    /****
     *
     * @var bool
     *
     * @Column(type="boolean", name="unlocked")
     */
    private $unlocked;

    /****
     *
     * @var Collection
     *
     * @ManyToMany(targetEntity="Model\Gallery\Gallery")
     * @JoinTable(name="article*article*galleries",
     *      joinColumns={@JoinColumn(name="article_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="gallery_id", referencedColumnName="id")})
     */
    private $galleries;

    /****
     *
     * @var Collection
     *
     * @ManyToMany(targetEntity="Model\User\User")
     * @JoinTable(name="article*article*authors",
     *      joinColumns={@JoinColumn(name="article_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="user_id", referencedColumnName="id")})
     */
    private $authors;

    /****
     *
     * @var Collection
     *
     * @OneToMany(targetEntity="Model\Article\Attachment", mappedBy="article")
     */
    private $attachments;
}

DDC-48: Cache Namespaces

Jira issue originally created by user mcurcio:

For users who run multiple doctrine 2 installations on a single machine, it is possible for APC/Memcache cache collisions to occur. One possible solution would allow the user to specify a namespace when creating the cache instance. I have attached such a solution. However, after reviewing DDC-47, there might be a better solution that addresses both requirements.

DDC-46: Invalid MySQL column mappings

Jira issue originally created by user mcurcio:

I have a table for storing sessions in the database, schema is:

CREATE TABLE IF NOT EXISTS Session (
id varchar(255) NOT NULL,
data longtext NOT NULL,
created datetime NOT NULL,
accessed datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

With the following code, I receive an error about an unknown 'clob' column. I believe the issue is related to the mappings in DBAL/Schema/MySQLSchemaManager::_getPortableTableColumnDefinition

Code:
$cmf = $em->getMetadataFactory();
$driver = $em->getConfiguration()->getMetadataDriverImpl();

    $driver->setClassDirectory(<model_path>);

    $classes = array();
    $preloadedClasses = $driver->preload();
    foreach ($preloadedClasses as $className) {
        $classes[] = $cmf->getMetadataFor($className);
    }

    $schemaTool = new \Doctrine\ORM\Tools\SchemaTool($em);

foreach ($schemaTool->getUpdateSchemaSql($classes) as $sql) {
        echo $sql.'<br />';
    }

Error:
exception 'Doctrine\Common\DoctrineException' with message 'Unknown column type ('clob')' in /var/www/tec-expo.com/development/libraries/Doctrine/Common/DoctrineException.php:109
Stack trace:
#0 [internal function]: Doctrine\Common\DoctrineException::**callStatic('unknownColumnTy...', Array)
#1 libraries/Doctrine/DBAL/Types/Type.php(125): Doctrine\Common\DoctrineException::unknownColumnType('clob')
#2 libraries/Doctrine/DBAL/Schema/AbstractSchemaManager.php(871): Doctrine\DBAL\Types\Type::getType('clob')
#3 libraries/Doctrine/DBAL/Schema/AbstractSchemaManager.php(180): Doctrine\DBAL\Schema\AbstractSchemaManager->_getPortableTableColumnList(Array)
#4 libraries/Doctrine/ORM/Tools/SchemaTool.php(504): Doctrine\DBAL\Schema\AbstractSchemaManager->listTableColumns('Session')
#5 (MVC controller): Doctrine\ORM\Tools\SchemaTool->getUpdateSchemaSql(Array)

DDC-43: offset and limit are in the wrong order (at least SQLite)

Jira issue originally created by user itoijala:

The following code creates an error:

Code:

$query = Itoijala_Singletons::getDoctrine()->createQueryBuilder();
$query->select('e')->from('Model\Guestbook\Entry e');
$query->andWhere('e.dateDeleted IS NULL')->andWhere('e.unlocked = TRUE');
$query->orderBy('e.dateCreated', 'DESC')->setFirstResult(($this->_getParam('page') - 1) * 15);
$query->setMaxResults(15);

$this->view->entries = $query->getQuery()->getResult();

Error:
SQLSTATE[HY000]: General error: 1 near "OFFSET": syntax error

The DQL:
SELECT e FROM Model\Guestbook\Entry e WHERE (e.dateDeleted IS NULL) AND (e.unlocked = TRUE) ORDER BY e.dateCreated DESC

The SQL:
SELECT g0_.id AS id0, g0_.name AS name1, g0_.email AS email2, g0_.homepage AS homepage3, g0_.content AS content4, g0_.comment AS comment5, g0_.unlocked AS unlocked6, g0_.date_created AS date_created7, g0_.date_updated AS date_updated8, g0_.date_deleted AS date_deleted9, g0_.creator_id AS creator_id10, g0_.updater_id AS updater_id11, g0_.deleter_id AS deleter_id12 FROM guestbook_entries g0_ WHERE (g0_.date_deleted IS NULL) AND (g0_.unlocked = 1) ORDER BY g0_.date_created DESC OFFSET 0 LIMIT 15

SQLite expects offset to come after limit. writeLimitClause in AbstractPlatform works correctly and is not overriden by SqlitePlatform. This means that the bug is somewhere else. writeLimitClause is not called.

DDC-15: Add support to --force option in SchemaTool CLI Task

Jira issue originally created by user romanb:

The way it's currently coded, schema-tool task is enabled --force by default.

This means that it'll attempt to execute every single SQL command without actually use error checking in SQL statements. One good example is if you attempt to --drop same schema twice. It'll generate a PDOException to you noticing that table does not exist (on second execution).

Instead of get errors on second attempt, it should gently notify it worked smoothly, except if --force is requested. To support this approach (specifically for --drop, but it should be applied for other types too), it is required to change the way we currently drop tables. Instead of do this:

DROP TABLE users;

It should try this approach:

DROP TABLE IF EXISTS users;

The idea is to --drop --force to execute like it is currently and --drop is only execute if exists approach. Same for --create, which means --force will attempt without care of existance in database. --create without --force check for previous existance and drop/create it again.

Problem is that not all drivers support it natively. Here is what my research gave me so far:

_SQLite_ (3.3)

DROP TABLE IF EXISTS users;

_MySQL_ (3.22)

DROP TABLE IF EXISTS users;

_PostgreSQL_

DROP TABLE IF EXISTS users;

_MS SQL Server_

IF EXISTS(SELECT TABLE*NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE*NAME = 'users') DROP TABLE users;

_Oracle_

declare 
  p_exists number :=0;
begin
  select nvl((select 1 from user*tables where table_name='TABLE1'  and rownum=1),0) into p*exists from dual ;
if p_exists = 1 then
  execute immediate '...

This is quite complex... maybe we should try:

IF (SELECT COUNT(1) FROM USER*TABLES WHERE TABLE*NAME = 'users') THEN DROP TABLE users;

Or...

if ((SELECT COUNT(1) FROM USER*TABLES WHERE TABLE*NAME = 'users') = 1) then execute immediate 'drop table users'; end if;

_DB2_

IF EXISTS (SELECT name FROM sysibm.systables WHERE name = 'users' ADN type = 'T') THEN
DROP TABLE users;
END IF;

_Informix_

Only information I got so far. Check if the table exists:

SELECT tabname FROM systables WHERE tabname='users';

DDC-47: Improve query resultset cache control

Jira issue originally created by user jwage:

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');

DDC-20: CLONE -cache problem with joined tables and external data change

Jira issue originally created by user psycon:

Doctrine doesn't invalidate cache properly. Queries like the one below has the second table taken from cache and it shouldn't.

$comp = Doctrine_Query::create()
            ->select('a.**, s.**')
            ->from('AttachedComponents a, a.SubscriptionComponents s')
            ->fetchOne();

In bug [DC-24] the advice is to select id of second table, I selected all fields in second table but doctrine doesn't seem to notice foreign key has changed.

DDC-26: Add support for subdirectories in classdir when using schema-tool --create

Jira issue originally created by user itoijala:

Currently when using schema-tool --create, all entity classes have to be in one directory. Subdirectories are not supported and result in errors. The iterator tries to require the subdirectories. This makes it impossible to use schema-tool --create to create the database for models that use namespaces and follow Doctrine rules for placing the files in subdirectories.

The schema-tool should iterate through all of the subdirectories of the classdir to find all of the entity classes. It should also not try to require() any directories.

DDC-33: Remove allowPartialObjects option.

Jira issue originally created by user romanb:

I think this option will cause unnecessary confusion. The best solution is to always disallow partial objects, yet you can force partial objects on individual object queries to increase performance if necessary. This is much simpler for the user than to remember all the details of how the current option affects certain behavior. Also, with the current default behavior of partial objects everywhere, some standard operations can unexpectedly not work, like adding an object to a collection of a managed object (but the collection itself was not fetched yet). As a result the collection will not be wrapped by doctrine with a PersistentCollection and modifications are lost.
There are more of such examples.

I will do this myself and I think this can even be done with full backwards compatibility (though its not strictly necessary since we're still in alpha).

This should be done before entering beta.

DDC-49: Incomplete MySQL Query Generator (MySQL Syntax error)

Jira issue originally created by user purnama:

i checkout the HEAD version. and try to write this DQL

$query = utilities\DataAccess::getEntityManager()->createQuery("SELECT
p, t FROM ".models\Phrase::CLASS_NAME." p join p.type t WHERE p.phrase
= '$phrase'");

i commented out the $config->setAllowPartialObjects(false);

and have PDO error that my MySQL statement sytax is invalid.

i check the Query that the Doctrine create and its like this :
SELECT p0_.phrase_id AS phrase_id0, p0_.phrase_name AS phrase_name1,
p1_.phrase_type_id AS phrase_type_id2, p1_.phrase_type_name AS
phrase_type_name3, p1_.phrase_type_abbreviation AS
phrase_type_abbreviation4 FROM phrase p0_ INNER JOIN phrase_type p1_
ON p0_.phrase_type_id = p1_. WHERE p0_.phrase_name = 'abu'

as you can si at the ON statement it writes p0_.phrase_type_id = p1_.

the p1_. is not completed. i think my DocAnnotation is OK, because i
look at the Doctrine Tests Models that test the OneToMany Function
(the one with the ECommerce models, product and features). I have
followed all the doc annotation writes there.

DDC-16: DQL Ignores properties of subclasses

Jira issue originally created by user ablock:

I have a classes B and C which inherit from superclass A. I would like
to get a list of all A's but filter the list to ignore those in C
which have a property d set to 2.

select a from A where a.d == 2 fails because "d" is not a property of A.

DDC-10: Complete association-mapping chapter

Jira issue originally created by user romanb:

The chapter about association mapping needs to be filled with the missing content. Many code examples can be taken from the functional ORM test cases.

DDC-5: Remove unsigned/fixed

Jira issue originally created by user romanb:

Changeset 6348 introduced unsigned/fixed properties for column metadata. Unsigned is completely unportable and fixed is unnecessary (we could simply introduce a fixed string type for this).

These 2 properties need to be removed.

DDC-41: Getting error with lazy loading via createQuery() followed by $em->flush()

Jira issue originally created by user crotalus:

Simple O-O relationship between \Entities\User and \Entities\Feed. Seems like there's a problem with not-yet lazy-loaded proxies and $em->flush().

<?php
namespace Entities;

/*** @Entity @Table(name="users_debug") **/
class User {
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
     * @OneToOne(targetEntity="Feed", mappedBy="User", cascade={"persist"})
     */
    private $Feed;

    public function getID() {
        return $this->id;
    }
    public function getFeed() {
        return $this->Feed;
    }
    public function setFeed($feed) {
        $this->Feed = $feed;
    }
}
?>

<?php
namespace Entities;

/****
 * @Entity @Table(name="feeds_debug")
 */
class Feed {
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO", allocationSize=1)
     */
    private $id;

     /****
     * @OneToOne(targetEntity="User", cascade={"persist"})
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $User;

    function setID($value) {
        $this->id = $value;
    }
    function getID() {
        return $this->id;
    }
    function getUser() {
        return $this->User;
    }
    function setUser($user) {
        $this->User = $user;
    }
}


?>

Table-data

users_debug:
 id
 361

feeds_debug:
 id  | user_id
 461 |     361

Code:

$user = $em->createQuery("SELECT u FROM Entities\User u WHERE u.id = 361")->getSingleResult();
print $user->getID(); // 361
// uncomment line below and it works
// print $user->getFeed()->getID();
$em->flush();

Error:
Warning: spl_object_hash() expects parameter 1 to be object, null given in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/UnitOfWork.php on line 1010
Warning: spl_object_hash() expects parameter 1 to be object, null given in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/UnitOfWork.php on line 566
Warning: ReflectionProperty::setValue() expects parameter 1 to be object, null given in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/UnitOfWork.php on line 575
Warning: get_class() expects parameter 1 to be object, null given in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/UnitOfWork.php on line 979
Fatal error: Uncaught exception 'ReflectionException' with message 'Class does not exist' in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadata.php:69
Stack trace:
#0 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadata.php(69): ReflectionClass->**construct(false)
#1 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(247): Doctrine\ORM\Mapping\ClassMetadata->**construct(false)
#2 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(177): Doctrine\ORM\Mapping\ClassMetadataFactory->_newClassMetadataInstance(false)
#3 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(115): Doctrine\ORM\Mapping\ClassMetadataFactory->_loadMetadata(false)
#4 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/EntityManager.php(212): Doctrine\ORM\Mapping\ClassMetadataFactory->getMetadataFor(false)
#5 /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/UnitOfWork.php(979): Doctrine\ORM\EntityManager->getClassMetadata in /home/crotalus/src/Doctrine2-Dev/lib/Doctrine/ORM/Mapping/ClassMetadata.php on line 69

PostgreSQL log:
2009-10-10 16:32:58 CEST LOGG: execute pdo_stmt_000000000a283af8: SELECT u0_.id AS id0 FROM users_debug u0_ WHERE u0_.id = 361
2009-10-10 16:32:58 CEST LOGG: sats: DEALLOCATE pdo_stmt_000000000a283af8
2009-10-10 16:32:58 CEST LOGG: execute pdo_stmt_000000000a283af8: SELECT NEXTVAL('feeds_debug_id_seq')
2009-10-10 16:32:58 CEST LOGG: sats: DEALLOCATE pdo_stmt_000000000a283af8
2009-10-10 16:32:58 CEST LOGG: execute pdo_stmt_000000000a283af8: SELECT NEXTVAL('users_debug_id_seq')
2009-10-10 16:32:58 CEST LOGG: sats: DEALLOCATE pdo_stmt_000000000a283af8

DDC-19: Can't unserialize serialized entity which has a proxy as a single valued relationship as a value

Jira issue originally created by user ablock:

namespace Test;
/****
 * @Entity
 */
class Book {
    /**** 
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
         * @OneToOne(targetEntity="Author",cascade={"persist"})
         * @JoinColumn(name="author_id", referencedColumnName="id")
         */
    private $author;

    public function setAuthor(Author $a) {
        $this->author = $a;
    }   

    public function getAuthor() {
        return $this->author;
    }
}

/****
 * @Entity
 */
class Author {
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
     * @Column(type="string")
     */
    private $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}
include 'entities.php';
include 'config.php';

$query = $em->createQuery('select b from Test\Book b where b.id = 1');
$book = $query->getSingleResult();
$book->getAuthor()->getName(); // If I don't do this, the object is not "loaded" and I can't serialize it.
file*put*contents('out',serialize($book));
include 'entities.php';
include 'config.php';
$b = unserialize(file*get*contents('out'));

This generates the error:

PHP Fatal error:  require(): Failed opening required '/home/ablock/doctrine/lib/Doctrine/Generated/Proxies/Test_AuthorAProxy.php'

DDC-14: Write "Events" chapter

Jira issue originally created by user romanb:

This chapter is still mostly empty and needs to be written. The basic structure stands.

DDC-21: Already fetched associations should not be overriden by subsequent queries.

Jira issue originally created by user romanb:

The discussion about this was brought up by DC-41. After checking the behavior of other ORMs (notably Hibernate), already fetched associations should not be overridden by subsequent queries, just like with other persistent state of already fetched entities. This saves performance and can assure a better integrity of the object model in-memory.

Entities and their associations that are already in-memory should only be refreshed if this is done explicitly either through EntityManager#refresh($entity) or through using the Query::HINT_REFRESH query hint on any query.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.