340 lines
9.1 KiB
Plaintext
340 lines
9.1 KiB
Plaintext
++ Introduction
|
|
|
|
The purpose of schema files is to allow you to manage your model definitions directly from a yaml file rather then editing php code. The yaml schema file is parsed and used to generate all your model definitions/classes.
|
|
|
|
++ Example Schema File
|
|
|
|
'tableName' and 'className' are optional. If not specified they will be set by the key of the yaml block
|
|
|
|
schema.yml
|
|
<code type="yml">
|
|
---
|
|
User:
|
|
columns:
|
|
id:
|
|
notnull: true
|
|
primary: true
|
|
autoincrement: true
|
|
type: integer
|
|
length: 4
|
|
name: id
|
|
username:
|
|
type: string
|
|
length: 255
|
|
relations:
|
|
Groups:
|
|
class: Group
|
|
refClass: UserGroup
|
|
local: user_id
|
|
foreign: group_id
|
|
type: many
|
|
UserGroup:
|
|
columns:
|
|
user_id:
|
|
type: integer
|
|
length: 4
|
|
primary: true
|
|
group_id:
|
|
type: integer
|
|
length: 4
|
|
primary: true
|
|
relations:
|
|
User:
|
|
local: user_id
|
|
foreign: id
|
|
Group:
|
|
local: group_id
|
|
foreign: id
|
|
Group:
|
|
columns:
|
|
id:
|
|
notnull: true
|
|
primary: true
|
|
autoincrement: true
|
|
type: integer
|
|
length: 4
|
|
name: id
|
|
name:
|
|
type: string
|
|
length: 255
|
|
relations:
|
|
Users:
|
|
class: User
|
|
refClass: UserGroup
|
|
local: group_id
|
|
foreign: user_id
|
|
type: many
|
|
</code>
|
|
|
|
And now we want to use some Doctrine code to parse that schema yml file and generate our models from it
|
|
|
|
<code type="php">
|
|
// This code will generate the models for schema.yml at /path/to/generate/models
|
|
$import = new Doctrine_Import_Schema();
|
|
$import->importSchema('schema.yml', 'yml', '/path/to/generate/models');
|
|
</code>
|
|
|
|
This is the directory structure that would be generated at /path/to/generate/models
|
|
|
|
<code>
|
|
- Group.class.php
|
|
- User.class.php
|
|
- UserGroup.class.php
|
|
- generated
|
|
- BaseGroup.class.php
|
|
- BaseUser.class.php
|
|
- BaseUserGroup.class.php
|
|
</code>
|
|
|
|
And finally here is the code for each of the generated models
|
|
|
|
<code type="php">
|
|
|
|
// Group.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
class Group extends BaseGroup
|
|
{
|
|
}
|
|
|
|
// User.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
class User extends BaseUser
|
|
{
|
|
}
|
|
|
|
// UserGroup.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
class UserGroup extends BaseUserGroup
|
|
{
|
|
}
|
|
|
|
// BaseGroup.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
abstract class BaseGroup extends sfDoctrineRecord
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
$this->setTableName('group');
|
|
$this->hasColumn('id', 'integer', 4, array('notnull' => true,
|
|
'primary' => true,
|
|
'autoincrement' => true));
|
|
$this->hasColumn('name', 'string', 255);
|
|
}
|
|
|
|
public function setUp()
|
|
{
|
|
$this->hasMany('User as Users', array('refClass' => 'UserGroup',
|
|
'local' => 'group_id',
|
|
'foreign' => 'user_id'));
|
|
}
|
|
}
|
|
|
|
// BaseUser.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
abstract class BaseUser extends sfDoctrineRecord
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
$this->setTableName('user_table');
|
|
$this->hasColumn('id', 'integer', 4, array('notnull' => true,
|
|
'primary' => true,
|
|
'autoincrement' => true));
|
|
$this->hasColumn('username', 'string', 255);
|
|
}
|
|
|
|
public function setUp()
|
|
{
|
|
$this->hasMany('Group as Groups', array('refClass' => 'UserGroup',
|
|
'local' => 'user_id',
|
|
'foreign' => 'group_id'));
|
|
}
|
|
}
|
|
|
|
// BaseUserGroup.class.php
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
abstract class BaseUserGroup extends sfDoctrineRecord
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
$this->setTableName('user_group');
|
|
$this->hasColumn('user_id', 'integer', 4, array('primary' => true));
|
|
$this->hasColumn('group_id', 'integer', 4, array('primary' => true));
|
|
}
|
|
|
|
public function setUp()
|
|
{
|
|
$this->hasOne('User', array('local' => 'user_id',
|
|
'foreign' => 'id'));
|
|
$this->hasOne('Group', array('local' => 'group_id',
|
|
'foreign' => 'id'));
|
|
}
|
|
}
|
|
</code>
|
|
|
|
++ Indexes
|
|
|
|
Please see chapter [doc basic-schema-mapping :index :name] for more information about indexes and their options.
|
|
|
|
schema.yml
|
|
<code type="yml">
|
|
---
|
|
UserProfile:
|
|
tableName: user_profile
|
|
columns:
|
|
user_id: { type: integer, length: 4, primary: true, autoincrement: true }
|
|
first_name: { type: string, length: 20 }
|
|
last_name: { type: string, length: 20 }
|
|
indexes:
|
|
name_index:
|
|
fields:
|
|
first_name:
|
|
sorting: ASC
|
|
length: 10
|
|
primary: true
|
|
last_name: ~
|
|
type: unique
|
|
</code>
|
|
|
|
This is the PHP line of code that is auto-generated inside setTableDefinition() inside your base model class.
|
|
|
|
Note: Don't mind the extra trailing commas. This is normal and they should not affect anything negatively.
|
|
|
|
<code type="php">
|
|
<?php
|
|
|
|
class BaseUserProfile extends Doctrine_Record
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
// code
|
|
|
|
$this->index('name_index', array('fields' => array('first_name' => array( 'sorting' => 'ASC', 'length' => '10', 'primary' => true, ), 'last_name' => array( ), ), 'type' => 'unique'));
|
|
}
|
|
}
|
|
|
|
?>
|
|
</code>
|
|
|
|
++ Additional Schema Options
|
|
|
|
It isn't necessary to define both sides of a relationship in the schema.yml file as doctrine will attempt to autocomplete the relationships for you. If you choose to define only one side of the relationship, there are two yaml options you can pass to help doctrine decide how to complete the opposite end of the relationship. For example.
|
|
|
|
schema.yml
|
|
<code type="yml">
|
|
---
|
|
Table1:
|
|
tableName: table_1
|
|
relations:
|
|
Table2Alias:
|
|
class: Table2
|
|
local: foreign_key
|
|
type: one
|
|
foreignAlias: Table1Alias
|
|
foreignType: one
|
|
columns:
|
|
column_1: { type: string, length: 128 }
|
|
foreign_key: { type: integer, length: 4 }
|
|
|
|
Table2:
|
|
tableName: table_2
|
|
columns:
|
|
column_1: { type: string, length: 128 }
|
|
foreign_key: { type: integer, length: 4 }
|
|
</code>
|
|
|
|
This schema will define a 1-1 relationship between Table1 and Table2. You'll notice there are two new yaml entries, foreignAlias, and foreignType. ForeignAlias will define the as Alias portion of the opposite relationship, and similarily foreignType defines the reverse relationship of the opposite relationship. Defining foreignType is only necessary when you want a one-to-one relationship, but do not want to define both ends of the relationship manually. The above schema produces the following classes.
|
|
|
|
<code type="php">
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
class Table1 extends Doctrine_Record
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
$this->setTableName('table_1');
|
|
$this->hasColumn('column_1', 'string', 128);
|
|
$this->hasColumn('foreign_key', 'integer', 4);
|
|
}
|
|
|
|
public function setUp()
|
|
{
|
|
$this->hasOne('Table2 as Table2Alias', array('local' => 'foreign_key',
|
|
'foreign' => 'id',
|
|
'onDelete' => 'CASCADE'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This class has been auto-generated by the Doctrine ORM Framework
|
|
*/
|
|
class Table2 extends Doctrine_Record
|
|
{
|
|
|
|
public function setTableDefinition()
|
|
{
|
|
$this->setTableName('table_2');
|
|
$this->hasColumn('column_1', 'string', 128);
|
|
$this->hasColumn('foreign_key', 'integer', 4);
|
|
}
|
|
|
|
public function setUp()
|
|
{
|
|
$this->hasOne('Table1 as Table1Alias', array('local' => 'id',
|
|
'foreign' => 'foreign_key'));
|
|
}
|
|
}
|
|
</code>
|
|
|
|
As you can see doctrine fully completes the relationship for both classes. You can also use this shorter format for m-to-m relationships. Using the same User and Groups models defined previously, we create a simplified schema.yml. Whereas in the one-to-many and one-to-one the foreignAlias isn't a required field. If you choose to create many-to-many relationships using the short yaml syntax, the foreignAlias is required for proper generation.
|
|
|
|
<code type="yml">
|
|
---
|
|
User:
|
|
columns:
|
|
id: { notnull: true, primary: true, autoincrement: true, type: integer, length: 4, name: id }
|
|
username: { type: string, length: 255 }
|
|
relations:
|
|
Groups:
|
|
class: Group
|
|
refClass: UserGroup
|
|
foreignAlias: Users
|
|
local: user_id
|
|
foreign: group_id
|
|
type: many
|
|
|
|
UserGroup:
|
|
columns:
|
|
user_id: { type: integer, length: 4, primary: true }
|
|
group_id: { type: integer, length: 4, primary: true }
|
|
|
|
Group:
|
|
columns:
|
|
id: { notnull: true, primary: true, autoincrement: true, type: integer, length: 4, name: id }
|
|
name: { type: string, length: 255 }
|
|
</code>
|
|
|
|
This schema will create identical classes as the fully defined schema.yml above. |