= Database Schema =

The schema for {{{schema.xml}}} contains a small number of elements with required and optional attributes.  The Propel generator contains a DTD (source:branches/1.3/generator/resources/dtd/database.dtd) that can be used to validate your {{{schema.xml}}} document.  Also, when you build your SQL and OM, the Propel generator will automatically validate your {{{schema.xml}}} file using a new, highly-detailed XSD (source:branches/1.3/generator/resources/xsd/database.xsd).

== At-a-Glance ==

The hierarchical tree relationship for the elements is:

{{{
#!xml
<database>
   <external-schema />
   <table>
     <column>
       <inheritance />
     </column>
     <foreign-key>
       <reference />
     </foreign-key>
     <index>
       <index-column />
     </index>
     <unique>
       <unique-column />
     </unique>
     <id-method-parameter/>
   </table>
</database>
}}}

== Detailed Reference ==

This page provides an alternate rendering of the Appendix B - Schema Reference from the user's guide.
It spells out in specific detail, just where each attribute or element belongs.

First, some conventions:

  *  Text surrounded by a '''/''' is text that you would provide and is not defined in the language. (i.e. a table name is a good example of this.)
  *  Optional items are surrounded by '''[''' and ''']''' characters.
  *  Items where you have an alternative choice have a '''|''' character between them (i.e. true|false)
  *  Alternative choices may be delimited by '''{''' and '''}''' to indicate that this is the default option, if not overridden elsewhere.
  *  '''...''' means repeat the previous item.

=== <database> element ===

Starting with the {{{<database>}}} element.  The ''attributes'' and ''elements'' available are:

{{{
#!xml
  <database
    name="/DatabaseName/"
    defaultIdMethod="native|none"
    [package="/ProjectName/"]
    [baseClass="/baseClassName/"]
    [basePeer="/baseClassPeerName/"]
    [defaultPhpNamingMethod="nochange|underscore|phpname"
    [heavyIndexing="true|false"]
  >
    <external-schema>
    <table>
    ...
  </database>
}}}

The {{{package}}}, {{{baseClass}}}, {{{basePeer}}}, {{{defaultPhpNamingMethod}}}, and {{{heavyIndexing}}} attributes are generally optional.
A Database element may include an {{{<external-schema>}}} element, or multiple {{{<table>}}} elements.

 * {{{baseClass}}} allows you to specify a default base class that all generated Propel objects should extend ({{{in place of propel.om.BaseObject}}}).
 * {{{basePeer}}} instructs Propel to use a different SQL-generating {{{BasePeer}}} class (or sub-class of {{{BasePeer}}}) for all generated objects.
 * {{{defaultIdMehtod}}} sets the default id method to use for auto-increment columns.
 * {{{defaultPhpNamingMethod}}} the default naming method to use.
 * {{{heavyIndexing}}} adds indexes for each component of the primary key (when using composite primary keys).
 * {{{package}}} specifies the "package" for the generated classes.

=== <external-schema> element ===

The {{{<external-schema>}}} element is pretty simple. It just includes a schema file from somewhere on the file systems.  The format is:

{{{
#!xml
  <external-schema filename="/a path to a file/" />
}}}

=== <table> element ===

The {{{<table>}}} element is the most complicated of the usable elements.  Its definition looks like this:

{{{
#!xml
  <table
     name = "/TableName/"
     [idMethod = "native|{none}"]
     [phpName = "/PhpObjectName/"]
     [skipSql = "true|false"]
     [abstract = "true|false"]
     [phpNamingMethod = "nochange|{underscore}|phpname"]
     [baseClass = "/baseClassName/"]
     [basePeer = "/baseClassPeerName/"]
     [description="/A text description of the table/"]
     [heavyIndexing = "true|false"]
     [readOnly = "true|false"]
     [treeMode = "NestedSet|MaterializedPath"]
     [reloadOnInsert = "true|false"]
     [reloadOnUpdate = "true|false"]
     [allowPkInsert = "true|false"]
  >

    <column>
    ...
    <foreign-key>
    ...
    <index>
    ...
    <unique>
    ...
    <id-method-parameter>
    ...
  </table>
}}}

According to the schema, {{{name}}} is the only required attribute.  Also, the {{{idMethod}}}, {{{phpNamingMethod}}}, {{{baseClass}}}, {{{basePeer}}}, and {{{heavyIndexing}}} attributes all default to what is specified by the {{{<database>}}} element.

==== Description of Attributes ====

 * {{{abstract}}} Whether the generated ''stub'' class will be abstract (e.g. if you're using inheritance)
 * {{{baseClass}}} allows you to specify a class that the generated Propel objects should extend ({{{in place of propel.om.BaseObject}}}).
 * {{{basePeer}}} instructs Propel to use a different SQL-generating {{{BasePeer}}} class (or sub-class of {{{BasePeer}}}).
 * {{{heavyIndexing}}} adds indexes for each component of the primary key (when using composite primary keys).
 * {{{idMethod}}} sets the id method to use for auto-increment columns.
 * {{{package}}} specifies the "package" for the generated classes.
 * {{{readOnly}}} suppresses the mutator/setter methods, save() and delete() methods.
 * {{{skipSql}}} instructs Propel not to generate DDL SQL for the specified table.  This can be used together with {{{readOnly}}} for supperting VIEWS in Propel.
 * {{{treeMode}}} is used to indicate that this table is part of a node tree.  Currently the only supported values are "!NestedSet" (see [wiki:Users/Documentation/1.3/Tree/NestedSet]) and "!MaterializedPath" (see: [wiki:Users/Documentation/1.3/Tree/MaterializedPath]).
 * {{{reloadOnInsert}}} is used to indicate that the object should be reloaded from the database when an INSERT is performed.  This is useful if you have triggers (or other server-side functionality like column default expressions) that alters the database row on INSERT.
 * {{{reloadOnUpdate}}} is used to indicate that the object should be reloaded from the database when an UPDATE is performed.  This is useful if you have triggers (or other server-side functionality like column default expressions) that alters the database row on UPDATE.
 * {{{allowPkInsert}}} can be used if you want to define the primary key of a new object being inserted. By default if idMethod is "native", Propel would throw an exception. However, in some cases this feature is useful, for example if you do some replication of data in an master-master environment. It defaults to false.

=== <column> element ===

{{{
#!xml
  <column
    name = "/ColumnName/"
    [phpName = "/PHPColumnName/"]
    [peerName = "/PEERNAME/"]
    [primaryKey = "true|{false}"]
    [required = "true|{false}"]
    [type = "BOOLEAN|TINYINT|SMALLINT|INTEGER|BIGINT|DOUBLE|FLOAT|REAL|DECIMAL|CHAR|{VARCHAR}|LONGVARCHAR|DATE|TIME|TIMESTAMP|BLOB|CLOB"]
    [phpType = "boolean|int|integer|double|float|string|/BuiltInClassName/|/UserDefinedClassName/"]
    [sqlType = "/NativeDatabaseColumnType/"
    [size = "/NumericLengthOfColumn/"]
    [scale = "/DigitsAfterDecimalPlace/"]
    [defaultValue = "/AnyDefaultValueMatchingType/"]
    [defaultExpr = "/AnyDefaultExpressionMatchingType/"]
    [autoIncrement = "true|{false}"]
    [lazyLoad = "true|{false}"]
    [description = "/Column Description/"]
    [primaryString = "true|{false}"]
    [phpNamingMethod = "nochange|underscore|phpname"]
    [inheritance = "single|{false}"]
    [inputValidator = "NameOfInputValidatorClass"]
   >
   [<inheritance key="/KeyName/" class="/ClassName/" [extends="/BaseClassName/"] />]
   </column>
}}}

==== Description of Attributes ====

 * {{{defaultValue}}} The default value that the object will have for this column in the PHP instance after creating a "new Object". This value is always interpreted as a string.
 * {{{defaultExpr}}} The default value for this column as expressed in SQL. This value is used solely for the "sql" target which builds your database from the schema.xml file. The defaultExpr is the SQL expression used as the "default" for the column.
 * {{{primaryString}}} A column defined as primary string serves as default value for a `__toString()` method in the generated Propel object.

=== <foreign-key> element ===

To link a column to another table use the following syntax:

{{{
#!xml
  <foreign-key
     foreignTable = "/TheOtherTableName/"
     [name = "/Name for this foreign key/"]
     [phpName = "/Name for the foreign object in methods generated in this class/"]
     [refPhpName = "/Name for this object in methods generated in the foreign class/"]
     [onDelete = "cascade|setnull|restrict|none"]
     [onUpdate = "cascade|setnull|restrict|none"]
  >
    <reference local="/LocalColumnName/" foreign="/ForeignColumnName/" />
  </foreign-key>
}}}

=== <index> element ===

To create an index on one or more columns, use the following syntax:

{{{
#!xml
  <index>
     <index-column name="/ColumnName/" [size="/LengthOfIndexColumn/"] />
     ...
  </index>
}}}

In some cases your RDBMS may require you to specify an index size.

=== <unique> element ===

To create a unique index on one or more columns, use the following syntax:

{{{
#!xml
  <unique>
     <unique-column name="/ColumnName/" [size="/LengthOfIndexColumn/"] />
     ...
  </unique>
}}}

In some cases your RDBMS may require you to specify an index size for unique indexes.

=== <id-method-parameter> element ===

If you are using a database that uses sequences for auto-increment columns (e.g. PostgreSQL or Oracle), you can customize the name of the sequence using  the <id-method-paramter/> tag:

{{{
#!xml
  <id-method-parameter value="my_custom_sequence_name"/>
}}}

== Column Types ==

Here are the Propel column types with some example mappings to native database and PHP types.  There are also several ways to customize the mapping between these types.

=== Text Types ===

||'''Propel Type'''||'''Desc'''||'''Example Default DB Type (MySQL)'''||'''Default PHP Native Type'''||
||CHAR||Fixed-lenght character data||CHAR||string||
||VARCHAR||Variable-lenght character data||VARCHAR||string||
||LONGVARCHAR||Long variable-length character data||TEXT||string||
||CLOB||Character LOB (locator object)||LONGTEXT||string||

=== Numeric Types ===

||'''Propel Type'''||'''Desc'''||'''Example Default DB Type (MySQL)'''||'''Default PHP Native Type'''||
||NUMERIC||Numeric data||DECIMAL||string (PHP int is limited)||
||DECIMAL||Decimal data||DECIMAL||string (PHP int is limited)||
||TINYINT||Tiny integer ||TINYINT||int||
||SMALLINT||Small integer ||SMALLINT||int||
||INTEGER||Integer||INTEGER||int||
||BIGINT||Large integer||BIGINT||string (PHP int is limited)||
||REAL||Real number||REAL||double||
||FLOAT||Floating point number||FLOAT||double||
||DOUBLE||Floating point number||DOUBLE||double||

=== Binary Types ===

||'''Propel Type'''||'''Desc'''||'''Example Default DB Type (MySQL)'''||'''Default PHP Native Type'''||
||BINARY||Fixed-length binary data||BLOB||double||
||VARBINARY||Variable-length binary data||MEDIUMBLOB||double||
||LONGVARBINARY||Long variable-length binary data||LONGBLOB||double||
||BLOB||Binary LOB (locator object)||LONGBLOB||string||

=== Temporal (Date/Time) Types ===


||'''Propel Type'''||'''Desc'''||'''Example Default DB Type (MySQL)'''||'''Default PHP Native Type'''||
||DATE||Date (e.g. YYYY-MM-DD)||DATE||DateTime object||
||TIME||Time (e.g. HH:MM:SS)||TIME||DateTime object||
||TIMESTAMP||Date + time (e.g. YYYY-MM-DD HH:MM:SS)||TIMESTAMP||DateTime object||

==== Legacy Temporal Types ====

The following Propel 1.2 types are still supported, but are no longer needed with Propel 1.3.

||'''Propel Type'''||'''Desc'''||'''Example Default DB Type (MySQL)'''||'''Default PHP Native Type'''||
||BU_DATE||Pre-/post-epoch date (e.g. 1201-03-02)||DATE||DateTime object||
||BU_TIMESTAMP||Pre-/post-epoch Date + time (e.g. 1201-03-02 12:33:00)||TIMESTAMP||DateTime object||

== Customizing Mappings ==

=== Specify Column Attributes ===

You can change the way that Propel maps its own types to native SQL types or to PHP types by overriding the values for a specific column.

For example:

(Overriding PHP type)
{{{
#!xml
<column name="population_served" type="INTEGER" phpType="string"/>
}}}

(Overriding SQL type)
{{{
#!xml
<column name="ip_address" type="VARCHAR" sqlType="inet"/>
}}}

=== Using Custom Platform ===

For overriding the mapping between Propel types and native SQL types, you can create your own Platform class and override the mapping.

For example:

{{{
#!php
<?php
require_once 'propel/engine/platform/MysqlPlatform .php';
class CustomMysqlPlatform extends MysqlPlatform {

	/**
	 * Initializes custom domain mapping.
	 */
	protected function initialize()
	{
		parent::initialize();
		$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB"));
		$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
	}
}
}}}

You must then specify that mapping in the {{{build.properties}}} for your project:

{{{
propel.platform.class = propel.engine.platform.${propel.database}Platform
}}}
