This commit is contained in:
parent
0c8ba8e9e2
commit
643fe70843
@ -1,5 +0,0 @@
|
||||
+++ Column naming
|
||||
+++ Column aliases
|
||||
+++ Default values
|
||||
+++ Data types
|
||||
+++ About type conversion
|
@ -1,14 +0,0 @@
|
||||
Doctrine offers a way of setting column aliases. This can be very useful when you want to keep the application logic separate from the database logic. For example if you want to change the name of the database field all you need to change at your application is the column definition.
|
||||
|
||||
<code type="php">
|
||||
class Book extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('bookName as name', 'string');
|
||||
}
|
||||
}
|
||||
$book = new Book();
|
||||
$book->name = 'Some book';
|
||||
$book->save();
|
||||
</code>
|
@ -1,8 +0,0 @@
|
||||
One problem with database compatibility is that many databases differ in their behaviour of how the result set of a query is returned. MySQL leaves the field names unchanged, which means if you issue a query of the form "SELECT myField FROM ..." then the result set will contain the field 'myField'.
|
||||
|
||||
Unfortunately, this is just the way MySql and some other databases do it. Postgres for example returns all field names in lowercase whilst Oracle returns all field names in uppercase. "So what? In what way does this influence me when using Doctrine?", you may ask. Fortunately, you don't have to bother about that issue at all.
|
||||
|
||||
Doctrine takes care of this problem transparently. That means if you define a derived Record class and define a field called 'myField' you will always access it through $record->myField (or $record['myField'], whatever you prefer) no matter whether you're using MySQL or Postgres or Oracle etc.
|
||||
|
||||
In short: You can name your fields however you want, using under_scores, camelCase or whatever you prefer.
|
||||
|
@ -1,255 +0,0 @@
|
||||
++++ Introduction
|
||||
|
||||
All DBMS provide multiple choice of data types for the information that can be stored in their database table fields. However, the set of data types made available varies from DBMS to DBMS.
|
||||
|
||||
To simplify the interface with the DBMS supported by Doctrine, it was defined a base set of data types that applications may access independently of the underlying DBMS.
|
||||
|
||||
The Doctrine applications programming interface takes care of mapping data types when managing database options. It is also able to convert that is sent to and received from the underlying DBMS using the respective driver.
|
||||
|
||||
The following data type examples should be used with Doctrine's createTable() method. The example array at the end of the data types section may be used with createTable() to create a portable table on the DBMS of choice (please refer to the main Doctrine documentation to find out what DBMS back ends are properly supported). It should also be noted that the following examples do not cover the creation and maintenance of indices, this chapter is only concerned with data types and the proper usage thereof.
|
||||
|
||||
It should be noted that the length of the column affects in database level type as well as application level validated length (the length that is validated with Doctrine validators).
|
||||
|
||||
Example 1. Column named 'content' with type 'string' and length 3000 results in database type 'TEXT' of which has database level length of 4000. However when the record is validated it is only allowed to have 'content' -column with maximum length of 3000.
|
||||
|
||||
Example 2. Column with type 'integer' and length 1 results in 'TINYINT' on many databases.
|
||||
|
||||
In general Doctrine is smart enough to know which integer/string type to use depending on the specified length.
|
||||
|
||||
|
||||
++++ Type modifiers
|
||||
|
||||
Within the Doctrine API there are a few modifiers that have been designed to aid in optimal table design. These are:
|
||||
|
||||
* The notnull modifiers
|
||||
* The length modifiers
|
||||
* The default modifiers
|
||||
* unsigned modifiers for some field definitions, although not all DBMS's support this modifier for integer field types.
|
||||
* zerofill modifiers (not supported by all drivers)
|
||||
* collation modifiers (not supported by all drivers)
|
||||
* fixed length modifiers for some field definitions.
|
||||
|
||||
Building upon the above, we can say that the modifiers alter the field definition to create more specific field types for specific usage scenarios. The notnull modifier will be used in the following way to set the default DBMS NOT NULL Flag on the field to true or false, depending on the DBMS's definition of the field value: In PostgreSQL the "NOT NULL" definition will be set to "NOT NULL", whilst in MySQL (for example) the "NULL" option will be set to "NO". In order to define a "NOT NULL" field type, we simply add an extra parameter to our definition array (See the examples in the following section)
|
||||
|
||||
<code type="php">
|
||||
'sometime' = array(
|
||||
'type' => 'time',
|
||||
'default' => '12:34:05',
|
||||
'notnull' => true,
|
||||
),
|
||||
</code>
|
||||
|
||||
Using the above example, we can also explore the default field operator. Default is set in the same way as the notnull operator to set a default value for the field. This value may be set in any character set that the DBMS supports for text fields, and any other valid data for the field's data type. In the above example, we have specified a valid time for the "Time" data type, '12:34:05'. Remember that when setting default dates and times, as well as datetimes, you should research and stay within the epoch of your chosen DBMS, otherwise you will encounter difficult to diagnose errors!
|
||||
|
||||
<code type="php">
|
||||
'sometext' = array(
|
||||
'type' => 'string',
|
||||
'length' => 12,
|
||||
),
|
||||
</code>
|
||||
|
||||
The above example will create a character varying field of length 12 characters in the database table. If the length definition is left out, Doctrine will create a length of the maximum allowable length for the data type specified, which may create a problem with some field types and indexing. Best practice is to define lengths for all or most of your fields.
|
||||
|
||||
|
||||
++++ Boolean
|
||||
|
||||
The boolean data type represents only two values that can be either 1 or 0. Do not assume that these data types are stored as integers because some DBMS drivers may implement this type with single character text fields for a matter of efficiency. Ternary logic is possible by using null as the third possible value that may be assigned to fields of this type.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('booltest', 'boolean');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Integer
|
||||
|
||||
The integer type is the same as integer type in PHP. It may store integer values as large as each DBMS may handle.
|
||||
|
||||
Fields of this type may be created optionally as unsigned integers but not all DBMS support it. Therefore, such option may be ignored. Truly portable applications should not rely on the availability of this option.
|
||||
|
||||
The integer type maps to different database type depending on the column length.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('integertest', 'integer', 4, array('unsigned' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Float
|
||||
|
||||
The float data type may store floating point decimal numbers. This data type is suitable for representing numbers within a large scale range that do not require high accuracy. The scale and the precision limits of the values that may be stored in a database depends on the DBMS that it is used.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('floattest', 'float');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ String
|
||||
|
||||
The text data type is available with two options for the length: one that is explicitly length limited and another of undefined length that should be as large as the database allows.
|
||||
|
||||
The length limited option is the most recommended for efficiency reasons. The undefined length option allows very large fields but may prevent the use of indexes, nullability and may not allow sorting on fields of its type.
|
||||
|
||||
The fields of this type should be able to handle 8 bit characters. Drivers take care of DBMS specific escaping of characters of special meaning with the values of the strings to be converted to this type.
|
||||
|
||||
By default Doctrine will use variable length character types. If fixed length types should be used can be controlled via the fixed modifier.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('stringtest', 'string', 200, array('fixed' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Array
|
||||
|
||||
This is the same as 'array' type in PHP.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('arraytest', 'array', 10000);
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Object
|
||||
|
||||
Doctrine supports objects as column types. Basically you can set an object to a field and Doctrine handles automatically the serialization / unserialization of that object.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('objecttest', 'object');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Blob
|
||||
|
||||
Blob (Binary Large OBject) data type is meant to store data of undefined length that may be too large to store in text fields, like data that is usually stored in files.
|
||||
|
||||
Blob fields are usually not meant to be used as parameters of query search clause (WHERE) unless the underlying DBMS supports a feature usually known as "full text search"
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('blobtest', 'blob');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Clob
|
||||
|
||||
Clob (Character Large OBject) data type is meant to store data of undefined length that may be too large to store in text fields, like data that is usually stored in files.
|
||||
|
||||
Clob fields are meant to store only data made of printable ASCII characters whereas blob fields are meant to store all types of data.
|
||||
|
||||
Clob fields are usually not meant to be used as parameters of query search clause (WHERE) unless the underlying DBMS supports a feature usually known as "full text search"
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('clobtest', 'clob');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Timestamp
|
||||
|
||||
The timestamp data type is a mere combination of the date and the time of the day data types. The representation of values of the time stamp type is accomplished by joining the date and time string values in a single string joined by a space. Therefore, the format template is YYYY-MM-DD HH:MI:SS. The represented values obey the same rules and ranges described for the date and time data types
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('timestamptest', 'timestamp');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Time
|
||||
|
||||
The time data type may represent the time of a given moment of the day. DBMS independent representation of the time of the day is also accomplished by using text strings formatted according to the ISO-8601 standard.
|
||||
|
||||
The format defined by the ISO-8601 standard for the time of the day is HH:MI:SS where HH is the number of hour the day from 00 to 23 and MI and SS are respectively the number of the minute and of the second from 00 to 59. Hours, minutes and seconds numbered below 10 should be padded on the left with 0.
|
||||
|
||||
Some DBMS have native support for time of the day formats, but for others the DBMS driver may have to represent them as integers or text values. In any case, it is always possible to make comparisons between time values as well sort query results by fields of this type.
|
||||
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('timetest', 'time');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Date
|
||||
|
||||
The date data type may represent dates with year, month and day. DBMS independent representation of dates is accomplished by using text strings formatted according to the IS0-8601 standard.
|
||||
|
||||
The format defined by the ISO-8601 standard for dates is YYYY-MM-DD where YYYY is the number of the year (Gregorian calendar), MM is the number of the month from 01 to 12 and DD is the number of the day from 01 to 31. Months or days numbered below 10 should be padded on the left with 0.
|
||||
|
||||
Some DBMS have native support for date formats, but for others the DBMS driver may have to represent them as integers or text values. In any case, it is always possible to make comparisons between date values as well sort query results by fields of this type.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('datetest', 'date');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Enum
|
||||
|
||||
Doctrine has a unified enum type. Enum typed columns automatically convert the string values into index numbers and vice versa. The possible values for the column can be specified with Doctrine_Record::setEnumValues(columnName, array values).
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('enumtest', 'enum', 4,
|
||||
array(
|
||||
'values' => array(
|
||||
'php',
|
||||
'java',
|
||||
'python'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
++++ Gzip
|
||||
|
||||
Gzip datatype is the same as string except that its automatically compressed when persisted and uncompressed when fetched. This datatype can be useful when storing data with a large compressibility ratio, such as bitmap images.
|
||||
|
||||
<code type="php">
|
||||
class Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('gziptest', 'gzip');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
Doctrine supports default values for all data types. When default value is attached to a record column this means two of things.
|
||||
First this value is attached to every newly created Record.
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('name', 'string', 50, array('default' => 'default name'));
|
||||
}
|
||||
}
|
||||
$user = new User();
|
||||
print $user->name; // default name
|
||||
</code>
|
||||
|
||||
Also when exporting record class to database DEFAULT //value// is attached to column definition statement.
|
@ -1,163 +0,0 @@
|
||||
+++ Introduction
|
||||
|
||||
//From [http://www.postgresql.org/docs/8.2/static/ddl-constraints.html PostgreSQL Documentation]://
|
||||
|
||||
> Data types are a way to limit the kind of data that can be stored in a table. For many applications, however, the constraint they provide is too coarse. For example, a column containing a product price should probably only accept positive values. But there is no standard data type that accepts only positive numbers. Another issue is that you might want to constrain column data with respect to other columns or rows. For example, in a table containing product information, there should be only one row for each product number.
|
||||
|
||||
Doctrine allows you to define *portable* constraints on columns and tables. Constraints give you as much control over the data in your tables as you wish. If a user attempts to store data in a column that would violate a constraint, an error is raised. This applies even if the value came from the default value definition.
|
||||
|
||||
Doctrine constraints act as database level constraints as well as application level validators. This means double security: the database doesn't allow wrong kind of values and neither does the application.
|
||||
|
||||
|
||||
+++ Notnull
|
||||
|
||||
A not-null constraint simply specifies that a column must not assume the null value. A not-null constraint is always written as a column constraint.
|
||||
|
||||
The following definition uses a notnull constraint for column {{name}}. This means that the specified column doesn't accept null values.
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string', 200, array('notnull' => true,
|
||||
'primary' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
When this class gets exported to database the following SQL statement would get executed (in MySQL):
|
||||
|
||||
<code type="sql">
|
||||
CREATE TABLE user (name VARCHAR(200) NOT NULL, PRIMARY KEY(name))
|
||||
</code>
|
||||
|
||||
The notnull constraint also acts as an application level validator. This means that if Doctrine validators are turned on, Doctrine will automatically check that specified columns do not contain null values when saved.
|
||||
|
||||
If those columns happen to contain null values {{Doctrine_Validator_Exception}} is raised.
|
||||
|
||||
|
||||
+++ Unique
|
||||
|
||||
Unique constraints ensure that the data contained in a column or a group of columns is unique with respect to all the rows in the table.
|
||||
|
||||
In general, a unique constraint is violated when there are two or more rows in the table where the values of all of the columns included in the constraint are equal. However, two null values are not considered equal in this comparison. That means even in the presence of a unique constraint it is possible to store duplicate rows that contain a null value in at least one of the constrained columns. This behavior conforms to the SQL standard, but some databases do not follow this rule. So be careful when developing applications that are intended to be portable.
|
||||
|
||||
The following definition uses a unique constraint for column {{name}}.
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string', 200, array('unique' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
>> Note: You should only use unique constraints for other than primary key columns. Primary key columns are always unique.
|
||||
|
||||
The following definition adds a unique constraint for columns {{name}} and {{age}}.
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string', 200);
|
||||
$this->hasColumn('age', 'integer', 2);
|
||||
|
||||
$this->unique(array('name', 'age'));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
+++ Check
|
||||
|
||||
Some of the Doctrine validators also act as database level check constraints. When a record with these validators is exported additional CHECK constraints are being added to CREATE TABLE statement.
|
||||
|
||||
Consider the following example which uses 'min' validator:
|
||||
|
||||
<code type="php">
|
||||
class Product extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', 4, 'primary');
|
||||
$this->hasColumn('price', 'decimal', 18, array('min' => 0));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
When exported the given class definition would execute the following statement (in pgsql):
|
||||
|
||||
<code type="sql">
|
||||
CREATE TABLE product (
|
||||
id INTEGER,
|
||||
price NUMERIC,
|
||||
PRIMARY KEY(id),
|
||||
CHECK (price >= 0))
|
||||
</code>
|
||||
|
||||
So Doctrine optionally ensures even at the database level that the price of any product cannot be below zero.
|
||||
|
||||
You can also set the maximum value of a column by using the 'max' validator. This also creates the equivalent CHECK constraint.
|
||||
|
||||
<code type="php">
|
||||
class Product extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', 4, 'primary');
|
||||
$this->hasColumn('price', 'decimal', 18, array('min' => 0, 'max' => 1000000));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
Generates (in pgsql):
|
||||
|
||||
<code type="sql">
|
||||
CREATE TABLE product (
|
||||
id INTEGER,
|
||||
price NUMERIC,
|
||||
PRIMARY KEY(id),
|
||||
CHECK (price >= 0),
|
||||
CHECK (price <= 1000000))
|
||||
</code>
|
||||
|
||||
Lastly you can create any kind of CHECK constraints by using the check() method of the Doctrine_Record. In the last example we add constraint to ensure that price is always higher than the discounted price.
|
||||
|
||||
<code type="php">
|
||||
class Product extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', 4, 'primary');
|
||||
$this->hasColumn('price', 'decimal', 18, array('min' => 0, 'max' => 1000000));
|
||||
$this->hasColumn('discounted_price', 'decimal', 18, array('min' => 0, 'max' => 1000000));
|
||||
|
||||
$this->check('price > discounted_price');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
Generates (in pgsql):
|
||||
|
||||
<code type="sql">
|
||||
CREATE TABLE product (
|
||||
id INTEGER,
|
||||
price NUMERIC,
|
||||
PRIMARY KEY(id),
|
||||
CHECK (price >= 0),
|
||||
CHECK (price <= 1000000),
|
||||
CHECK (price > discounted_price))
|
||||
</code>
|
||||
|
||||
|
||||
> NOTE: some databases don't support CHECK constraints. When this is the case Doctrine simple skips the creation of check constraints.
|
||||
|
||||
If the Doctrine validators are turned on the given definition would also ensure that when a record is being saved its price is always greater than zero.
|
||||
|
||||
If some of the prices of the saved products within a transaction is below zero, Doctrine throws Doctrine_Validator_Exception and automatically rolls back the transaction.
|
||||
|
@ -1,119 +0,0 @@
|
||||
+++ Introduction
|
||||
|
||||
Indexes are used to find rows with specific column values quickly. Without an index, the database must begin with the first row and then read through the entire table to find the relevant rows.
|
||||
|
||||
The larger the table, the more this consumes time. If the table has an index for the columns in question, the database can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading rows one-by-one.
|
||||
|
||||
Indexes come with a cost as they slow down the inserts and updates. However, in general you should **always** use indexes for the fields that are used in SQL where conditions.
|
||||
|
||||
|
||||
+++ Adding indexes
|
||||
|
||||
You can add indexes by simple calling {{Doctrine_Record::index('indexName', $definition)}} where {{$definition}} is the definition array.
|
||||
|
||||
An example of adding a simple index to field called {{name}}:
|
||||
|
||||
<code type="php">
|
||||
class IndexTest extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
|
||||
$this->index('myindex', array('fields' => 'name');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
An example of adding a multi-column index to field called {{name}}:
|
||||
|
||||
<code type="php">
|
||||
class MultiColumnIndexTest extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
$this->hasColumn('code', 'string');
|
||||
|
||||
$this->index('myindex', array('fields' => array('name', 'code')));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
An example of adding a multiple indexes on same table:
|
||||
|
||||
<code type="php">
|
||||
class MultipleIndexTest extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
$this->hasColumn('code', 'string');
|
||||
$this->hasColumn('age', 'integer');
|
||||
|
||||
$this->index('myindex', array('fields' => array('name', 'code')));
|
||||
$this->index('ageindex', array('fields' => array('age'));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
+++ Index options
|
||||
|
||||
Doctrine offers many index options, some of them being db-specific. Here is a full list of available options:
|
||||
|
||||
<code>
|
||||
sorting => string('ASC' / 'DESC')
|
||||
what kind of sorting does the index use (ascending / descending)
|
||||
|
||||
length => integer
|
||||
index length (only some drivers support this)
|
||||
|
||||
primary => boolean(true / false)
|
||||
whether or not the index is primary index
|
||||
|
||||
type => string('unique', -- supported by most drivers
|
||||
'fulltext', -- only availible on Mysql driver
|
||||
'gist', -- only availible on Pgsql driver
|
||||
'gin') -- only availible on Pgsql driver
|
||||
</code>
|
||||
|
||||
<code type="php">
|
||||
class MultipleIndexTest extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
$this->hasColumn('code', 'string');
|
||||
$this->hasColumn('age', 'integer');
|
||||
|
||||
$this->index('myindex', array(
|
||||
'fields' => array(
|
||||
'name' =>
|
||||
array('sorting' => 'ASC',
|
||||
'length' => 10),
|
||||
'code'),
|
||||
'type' => 'unique',
|
||||
));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
+++ Special indexes
|
||||
|
||||
Doctrine supports many special indexes. These include Mysql FULLTEXT and Pgsql GiST indexes. In the following example we define a Mysql FULLTEXT index for the field 'content'.
|
||||
|
||||
<code type="php">
|
||||
class Article
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
$this->hasColumn('content', 'string');
|
||||
|
||||
$this->index('content', array('fields' => 'content',
|
||||
'type' => 'fulltext'));
|
||||
}
|
||||
}
|
||||
</code>
|
@ -1,43 +0,0 @@
|
||||
Doctrine_Record::hasColumn() takes 4 arguments:
|
||||
|
||||
# **column name**
|
||||
# **column type**
|
||||
# **column length**
|
||||
# **column constraints and validators**
|
||||
|
||||
<code type="php">
|
||||
class Email extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
// setting custom table name:
|
||||
$this->setTableName('emails');
|
||||
|
||||
$this->hasColumn('address', // name of the column
|
||||
'string', // column type
|
||||
'200', // column length
|
||||
array('notblank' => true,
|
||||
'email' => true // validators / constraints
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$this->hasColumn('address2', // name of the column
|
||||
'string', // column type
|
||||
'200', // column length
|
||||
// validators / constraints without arguments can be
|
||||
// specified also as as string with | separator
|
||||
'notblank|email'
|
||||
);
|
||||
|
||||
// Doctrine even supports the following format for
|
||||
// validators / constraints which have no arguments:
|
||||
|
||||
$this->hasColumn('address3', // name of the column
|
||||
'string', // column type
|
||||
'200', // column length
|
||||
array('notblank', 'email')
|
||||
);
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
Note that validators / column constraints and the column length fields are optional. The length may be omitted by using **null** for the length argument, allowing doctrine to use a default length and permitting a fourth argument for validation or column constraints.
|
@ -1,133 +0,0 @@
|
||||
+++ Introduction
|
||||
|
||||
Doctrine supports many kind of identifiers. For most cases it is recommended not to specify any primary keys (Doctrine will then use field name {{id}} as an autoincremented primary key). When using table creation Doctrine is smart enough to emulate the autoincrementation with sequences and triggers on databases that doesn't support it natively.
|
||||
|
||||
|
||||
+++ Natural
|
||||
|
||||
Natural identifier is a property or combination of properties that is unique and non-null. The use of natural identifiers is encouraged.
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string', 200, array('primary' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
+++ Autoincremented
|
||||
Autoincrement primary key is the most basic identifier and its usage is strongly encouraged. Sometimes you may want to use some other name than {{id}} for your autoinc primary key. It can be specified as follows:
|
||||
|
||||
<code type="php">
|
||||
class User extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn('uid', 'integer', 20, array('primary' => true, 'autoincrement' => true));
|
||||
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
You should consider using autoincremented or sequential primary keys only when the record cannot be identified naturally (in other words it doesn't have a natural identifier).
|
||||
|
||||
The following example shows why natural identifiers are more efficient.
|
||||
|
||||
Consider three classes Permission, Role and RolePermission. Roles having many permissions and vice versa (so their relation is many-to-many). Now lets also assume that each role and permission are naturally identified by their names.
|
||||
|
||||
Now adding autoincremented primary keys to these classes would be simply stupid. It would require more data and it would make the queries more inefficient. For example fetching all permissions for role 'Admin' would be done as follows (when using autoinc pks):
|
||||
|
||||
<code type="sql">
|
||||
SELECT p.*
|
||||
FROM Permission p
|
||||
LEFT JOIN RolePermission rp ON rp.permission_id = p.id
|
||||
LEFT JOIN Role r ON rp.role_id = r.id
|
||||
WHERE r.name = 'Admin'
|
||||
</code>
|
||||
|
||||
Now remember sql JOINS are always expensive and here we are using two of those. When using natural identifiers the query would look like:
|
||||
|
||||
<code type="sql">
|
||||
SELECT p.*
|
||||
FROM Permission p
|
||||
LEFT JOIN RolePermission rp ON rp.permission_name = p.name
|
||||
WHERE rp.role_name = 'Admin'
|
||||
</code>
|
||||
|
||||
Thats -1 JOIN !
|
||||
|
||||
+++ Composite
|
||||
|
||||
Composite primary key can be used efficiently in association tables (tables that connect two components together). It is not recommended to use composite primary keys in anywhere else as Doctrine does not support mapping relations on multiple columns.
|
||||
|
||||
Due to this fact your doctrine-based system will scale better if it has autoincremented primary key even for association tables.
|
||||
|
||||
<code type="php">
|
||||
class Groupuser extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('user_id', 'integer', 20, array('primary' => true));
|
||||
$this->hasColumn('group_id', 'integer', 20, array('primary' => true));
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
|
||||
+++ Sequence
|
||||
|
||||
Doctrine supports sequences for generating record identifiers. Sequences are a way of offering unique IDs for data rows. If you do most of your work with e.g. MySQL, think of sequences as another way of doing {{AUTO_INCREMENT}}.
|
||||
|
||||
Doctrine knows how to do sequence generation in the background so you don't have to worry about calling database specific queries - Doctrine does it for you, all you need to do is define a column as a sequence column and optionally provide the name of the sequence table and the id column name of the sequence table.
|
||||
|
||||
Consider the following record definition:
|
||||
|
||||
<code type="php">
|
||||
class Book extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', null, array('primary' => true, 'sequence' => true));
|
||||
$this->hasColumn('name', 'string');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
By default Doctrine uses the following format for sequence tables {{[tablename]_seq}}. If you wish to change this you can use the following piece of code to change the formatting:
|
||||
|
||||
<code type="php">
|
||||
$manager = Doctrine_Manager::getInstance();
|
||||
$manager->setAttribute(Doctrine::ATTR_SEQNAME_FORMAT, '%s_my_seq');
|
||||
</code>
|
||||
|
||||
Doctrine uses column named id as the sequence generator column of the sequence table. If you wish to change this globally (for all connections and all tables) you can use the following code:
|
||||
|
||||
<code type="php">
|
||||
$manager = Doctrine_Manager::getInstance();
|
||||
$manager->setAttribute(Doctrine::ATTR_SEQCOL_NAME, 'my_seq_column');
|
||||
</code>
|
||||
|
||||
In the following example we do not wish to change global configuration we just want to make the {{id}} column to use sequence table called {{book_sequence}}. It can be done as follows:
|
||||
|
||||
<code type="php">
|
||||
class Book extends Doctrine_Record {
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', null, array('primary', 'sequence' => 'book_sequence'));
|
||||
$this->hasColumn('name', 'string');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
Here we take the preceding example a little further: we want to have a custom sequence column. Here it goes:
|
||||
|
||||
<code type="php">
|
||||
class Book extends Doctrine_Record {
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('id', 'integer', null, array('primary', 'sequence' => array('book_sequence', 'sequence')));
|
||||
$this->hasColumn('name', 'string');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
@ -1,12 +0,0 @@
|
||||
Doctrine automatically creates table names from the record class names. For this reason, it is recommended to name your record classes using the following rules:
|
||||
|
||||
* Use {{CamelCase}} naming
|
||||
* Underscores are allowed
|
||||
* The first letter must be capitalized
|
||||
* The class name cannot be one of the following (these keywords are reserved in DQL API):
|
||||
* {{ALL}}, {{AND}}, {{ANY}}, {{AS}}, {{ASC}}, {{AVG}}, {{BETWEEN}}, {{BIT_LENGTH}}, {{BY}}, {{CHARACTER_LENGTH}}, {{CHAR_LENGTH}}, {{COUNT}}, {{CURRENT_DATE}}, {{CURRENT_TIME}}, {{CURRENT_TIMESTAMP}}, {{DELETE}}, {{DESC}}, {{DISTINCT}}, {{EMPTY}}, {{EXISTS}}, {{FALSE}}, {{FETCH}}, {{FROM}}, {{GROUP}}, {{HAVING}}, {{IN}}, {{INDEXBY}}, {{INNER}}, {{IS}}, {{JOIN}}, {{LEFT}}, {{LIKE}}, {{LOWER}}, {{MAX}}, {{MEMBER}}, {{MIN}}, {{MOD}}, {{NEW}}, {{NOT}}, {{NULL}}, {{OBJECT}}, {{OF}}, {{OR}}, {{ORDER}}, {{OUTER}}, {{POSITION}}, {{SELECT}}, {{SOME}}, {{SUM}}, {{TRIM}}, {{TRUE}}, {{UNKNOWN}}, {{UPDATE}}, {{UPPER}} and {{WHERE}}.
|
||||
|
||||
**Example:** {{My_PerfectClass}}
|
||||
|
||||
If you need to use a different naming schema, you can override this using the {{setTableName()}} method in the {{setTableDefinition()}} method.
|
||||
|
@ -1,44 +0,0 @@
|
||||
Doctrine offers various table options. All table options can be set via {{Doctrine_Record::option($optionName, $value)}}.
|
||||
|
||||
For example if you are using MySQL and want to use INNODB tables it can be done as follows:
|
||||
|
||||
<code type="php">
|
||||
class MyInnoDbRecord extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
|
||||
$this->option('type', 'INNODB');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
In the following example we set the collate and character set options:
|
||||
|
||||
<code type="php">
|
||||
class MyCustomOptionRecord extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
|
||||
$this->option('collate', 'utf8_unicode_ci');
|
||||
$this->option('charset', 'utf8');
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
Doctrine offers the ability to turn off foreign key constraints for specific Models.
|
||||
|
||||
<code type="php">
|
||||
class MyCustomOptionRecord extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('name', 'string');
|
||||
|
||||
$this->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL ^ Doctrine::EXPORT_CONSTRAINTS);
|
||||
}
|
||||
}
|
||||
</code>
|
Loading…
x
Reference in New Issue
Block a user