<commit_before>++ Dealing with relations
++ Many-to-Many relations
+++ Creating a new link
Lets say we have two classes User and Group which are linked trhough a GroupUser association class. When working with transient (new) records the fastest way for adding a User and couple of Groups for it is:
<code type="php">
$user = new User();
$user->name = 'Some User';
$user->Group[0]->name = 'Some Group';
$user->Group[1]->name = 'Some Other Group';
$user->save();
</code>

However in real world scenarious you often already have existing groups, where you want to add a given user. The most efficient way of doing this is:
<code type="php">
$gu = new GroupUser();
$gu->user_id = $userId;
$gu->group_id = $groupId;
$gu->save();
</code>

+++ Deleting a link

The right way to delete links between many-to-many associated records is by using the DQL DELETE statement. Convenient and recommended way of using DQL DELETE is trhough the Query API.

<code type="php">
$deleted = Doctrine_Query::create()
           ->delete()
           ->from('GroupUser')
           ->addWhere('user_id = 5')
           ->whereIn('group_id', $groupIds);
           ->execute();
// print out the deleted links
print $deleted;
</code>

Another way to {{unlink}} the relationships between related objects is through the {{Doctrine_Record::unlink}} method. However, you should avoid using this method unless you already have the parent model, since it involves querying the database first.

<code type="php">
$user = $conn->getTable('User')->find(5);
$user->unlink('Group', array(0, 1));
$user->save();

// you can also unlink ALL relationships to Group
$user->unlink('Group');
</code>

While the obvious and convinient way of deleting a link between User and Group would be the following, you still should *NOT* do this:

<code type="php">
$user = $conn->getTable('User')->find(5);
$user->GroupUser
     ->remove(0)
     ->remove(1);
$user->save();
</code>

This is due to a fact that $user->GroupUser loads all group links for given user. This can time-consuming task if user belongs to many groups. Even if the user belongs to few groups this will still execute an unnecessary SELECT statement.

++ Fetching objects

Normally when you fetch data from database the following phases are executed:

1. Sending the query to database
2. Retrieve the returned data from the database

In terms of object fetching we call these two phases the 'fetching' phase. Doctrine also has another phase called hydration phase. The hydration phase takes place whenever you are fecthing structured arrays / objects. Unless explicitly specified everything in Doctrine gets hydrated.

Lets consider we have users and phonenumbers with their relation being one-to-many. Now consider the following plain sql query:

<code type="php">
$dbh->fetchAll('SELECT u.id, u.name, p.phonenumber FROM user u LEFT JOIN phonenumber p ON u.id = p.user_id');
</code>

If you are familiar with these kind of one-to-many joins it may be familiar to you how the basic result set is constructed. Whenever the user has more than one phonenumbers there will be duplicated data in the result set. The result set might look something like:

<code>
 index  | u.id | u.name         | p.phonenumber |
 0      |   1  | <NAME>   | 123 123       |
 1      |   1  | <NAME>   | 456 456       |
 2      |   2  | <NAME>      | 111 111       |
 3      |   3  | <NAME>     | 222 222       |
 4      |   3  | <NAME>     | 333 333       |
 5      |   3  | <NAME>     | 444 444       |
</code>

Here <NAME> has 2 phonenumbers, <NAME> has one whereas <NAME> has 3 phonenumbers. You may notice how clumsy this result set is. Its hard to iterate over it as you would need some duplicate data checkings here and there. 

Doctrine hydration removes all duplicated data. It also performs many other things such as:

# Custom indexing of result set elements
# Value casting and preparation
# Value assignment listening
# Makes multi-dimensional array out of the two-dimensional result set array, the number of dimensions is equal to the number of nested joins

Now consider the DQL equivalent of the SQL query we used:
<code type="php">
$array = $conn->query('SELECT u.id, u.name, p.phonenumber FROM User u LEFT JOIN u.Phonenumber p', 
                      array(), Doctrine::HYDRATE_ARRAY);
</code>

The structure of this hydrated array would look like:

<code>
array(0 => array('id' => 1,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '123 123'),
                          1 => array('phonenumber' => '456 456'))),
      1 => array('id' => 2,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '111 111'))),
      2 => array('id' => 3,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '111 111')),
                          2 => array('phonenumber' => '222 222'),
                          3 => array('phonenumber' => '333 333'))));
</code>

This structure also applies to the hydration of objects(records) which is the default hydration mode of Doctrine. The only differences are that the individual elements are represented as Doctrine_Record objects and the arrays converted into Doctrine_Collection objects. Whether dealing with arrays or objects you can:

# Iterate over the results using //foreach//
# Access individual elements using array access brackets 
# Get the number of elements using //count()// function
# Check if given element exists using //isset()//
# Unset given element using //unset()//

You should always use array hydration when you only need to data for access-only purposes, whereas you should use the record hydration when you need to change the fetched data.

The constant O(n) performance of the hydration algorithm is ensured by a smart identifier caching solution.

+++ Field lazy-loading

Whenever you fetch an object that has not all of its fields loaded from database then the state of this object is called proxy. Proxy objects can load the unloaded fields lazily.

Lets say we have a User class with the following definition:

<code type="php">
class User extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('name', 'string', 20);
        $this->hasColumn('password', 'string', 16);
        $this->hasColumn('description', 'string');
    }
}
</code>

In the following example we fetch all the Users with the fields name and password loaded directly. Then we lazy-load a huge field called description for one user.

<code type="php">
$users = Doctrine_Query::create()->select('u.name, u.password')->from('User u')->execute();

// the following lazy-loads the description fields and executes one additional database query
$users[0]->description;
</code>

Doctrine does the proxy evaluation based on loaded field count. It does not evaluate which fields are loaded on field-by-field basis. The reason for this is simple: performance. Field lazy-loading is very rarely needed in PHP world, hence introducing some kind of variable to check which fields are loaded would introduce unnecessary overhead to basic fetching.<commit_msg>Added docs for the construct() method<commit_after>++ Dealing with relations
++ Many-to-Many relations
+++ Creating a new link
Lets say we have two classes User and Group which are linked trhough a GroupUser association class. When working with transient (new) records the fastest way for adding a User and couple of Groups for it is:
<code type="php">
$user = new User();
$user->name = 'Some User';
$user->Group[0]->name = 'Some Group';
$user->Group[1]->name = 'Some Other Group';
$user->save();
</code>

However in real world scenarious you often already have existing groups, where you want to add a given user. The most efficient way of doing this is:
<code type="php">
$gu = new GroupUser();
$gu->user_id = $userId;
$gu->group_id = $groupId;
$gu->save();
</code>

+++ Deleting a link

The right way to delete links between many-to-many associated records is by using the DQL DELETE statement. Convenient and recommended way of using DQL DELETE is trhough the Query API.

<code type="php">
$deleted = Doctrine_Query::create()
           ->delete()
           ->from('GroupUser')
           ->addWhere('user_id = 5')
           ->whereIn('group_id', $groupIds);
           ->execute();
// print out the deleted links
print $deleted;
</code>

Another way to {{unlink}} the relationships between related objects is through the {{Doctrine_Record::unlink}} method. However, you should avoid using this method unless you already have the parent model, since it involves querying the database first.

<code type="php">
$user = $conn->getTable('User')->find(5);
$user->unlink('Group', array(0, 1));
$user->save();

// you can also unlink ALL relationships to Group
$user->unlink('Group');
</code>

While the obvious and convinient way of deleting a link between User and Group would be the following, you still should *NOT* do this:

<code type="php">
$user = $conn->getTable('User')->find(5);
$user->GroupUser
     ->remove(0)
     ->remove(1);
$user->save();
</code>

This is due to a fact that $user->GroupUser loads all group links for given user. This can time-consuming task if user belongs to many groups. Even if the user belongs to few groups this will still execute an unnecessary SELECT statement.

++ Fetching objects

Normally when you fetch data from database the following phases are executed:

1. Sending the query to database
2. Retrieve the returned data from the database

In terms of object fetching we call these two phases the 'fetching' phase. Doctrine also has another phase called hydration phase. The hydration phase takes place whenever you are fecthing structured arrays / objects. Unless explicitly specified everything in Doctrine gets hydrated.

Lets consider we have users and phonenumbers with their relation being one-to-many. Now consider the following plain sql query:

<code type="php">
$dbh->fetchAll('SELECT u.id, u.name, p.phonenumber FROM user u LEFT JOIN phonenumber p ON u.id = p.user_id');
</code>

If you are familiar with these kind of one-to-many joins it may be familiar to you how the basic result set is constructed. Whenever the user has more than one phonenumbers there will be duplicated data in the result set. The result set might look something like:

<code>
 index  | u.id | u.name         | p.phonenumber |
 0      |   1  | <NAME>   | 123 123       |
 1      |   1  | <NAME>   | 456 456       |
 2      |   2  | <NAME>      | 111 111       |
 3      |   3  | <NAME>     | 222 222       |
 4      |   3  | <NAME>     | 333 333       |
 5      |   3  | <NAME>     | 444 444       |
</code>

Here <NAME> has 2 phonenumbers, <NAME> has one whereas <NAME> has 3 phonenumbers. You may notice how clumsy this result set is. Its hard to iterate over it as you would need some duplicate data checkings here and there. 

Doctrine hydration removes all duplicated data. It also performs many other things such as:

# Custom indexing of result set elements
# Value casting and preparation
# Value assignment listening
# Makes multi-dimensional array out of the two-dimensional result set array, the number of dimensions is equal to the number of nested joins

Now consider the DQL equivalent of the SQL query we used:
<code type="php">
$array = $conn->query('SELECT u.id, u.name, p.phonenumber FROM User u LEFT JOIN u.Phonenumber p', 
                      array(), Doctrine::HYDRATE_ARRAY);
</code>

The structure of this hydrated array would look like:

<code>
array(0 => array('id' => 1,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '123 123'),
                          1 => array('phonenumber' => '456 456'))),
      1 => array('id' => 2,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '111 111'))),
      2 => array('id' => 3,
                 'name' => '<NAME>',
                 'Phonenumber' =>
                    array(0 => array('phonenumber' => '111 111')),
                          2 => array('phonenumber' => '222 222'),
                          3 => array('phonenumber' => '333 333'))));
</code>

This structure also applies to the hydration of objects(records) which is the default hydration mode of Doctrine. The only differences are that the individual elements are represented as Doctrine_Record objects and the arrays converted into Doctrine_Collection objects. Whether dealing with arrays or objects you can:

# Iterate over the results using //foreach//
# Access individual elements using array access brackets 
# Get the number of elements using //count()// function
# Check if given element exists using //isset()//
# Unset given element using //unset()//

You should always use array hydration when you only need to data for access-only purposes, whereas you should use the record hydration when you need to change the fetched data.

The constant O(n) performance of the hydration algorithm is ensured by a smart identifier caching solution.

+++ Field lazy-loading

Whenever you fetch an object that has not all of its fields loaded from database then the state of this object is called proxy. Proxy objects can load the unloaded fields lazily.

Lets say we have a User class with the following definition:

<code type="php">
class User extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('name', 'string', 20);
        $this->hasColumn('password', 'string', 16);
        $this->hasColumn('description', 'string');
    }
}
</code>

In the following example we fetch all the Users with the fields name and password loaded directly. Then we lazy-load a huge field called description for one user.

<code type="php">
$users = Doctrine_Query::create()->select('u.name, u.password')->from('User u')->execute();

// the following lazy-loads the description fields and executes one additional database query
$users[0]->description;
</code>

Doctrine does the proxy evaluation based on loaded field count. It does not evaluate which fields are loaded on field-by-field basis. The reason for this is simple: performance. Field lazy-loading is very rarely needed in PHP world, hence introducing some kind of variable to check which fields are loaded would introduce unnecessary overhead to basic fetching.

++ Overriding the constructor

Sometimes you want to do some operations at the creation time of your objects. Doctrine doesn't allow you to override the Doctrine_Record::__construct() method but provides an alternative:

<code type="php">
class User extends Doctrine_Record
{
    public function construct()
    {
        $this->name = '<NAME>';
        $this->do_something();
    }
}
</code>

The only drawback is that it doesn't provide a way to pass parameters to the constructor.
{'fraction_non_alphanumeric': 0.0971935204319712, 'fraction_numerical': 0.015198986734217719, 'mean_word_length': 3.310919540229885, 'pattern_counts': {'":': 0, '<': 74, '<?xml version=': 0, '>': 194, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5655196', 'n_tokens_mistral': 4184, 'n_tokens_neox': 3914, 'n_words': 1921}