Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
c0d023c5
Commit
c0d023c5
authored
Jan 22, 2010
by
beberlei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] Removed accidentlly committed .orig patch files.
parent
4bec3e2c
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
0 additions
and
3696 deletions
+0
-3696
AbstractPlatform.php.orig
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php.orig
+0
-1814
AnnotationDriver.php.orig
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php.orig
+0
-374
XmlDriver.php.orig
lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php.orig
+0
-452
YamlDriver.php.orig
lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php.orig
+0
-451
SchemaTool.php.orig
lib/Doctrine/ORM/Tools/SchemaTool.php.orig
+0
-605
No files found.
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php.orig
deleted
100644 → 0
View file @
4bec3e2c
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\DBAL\Platforms
;
use
Doctrine\DBAL\DBALException
,
Doctrine\DBAL\Connection
,
Doctrine\DBAL\Types
,
Doctrine\DBAL\Schema\Table
,
Doctrine\DBAL\Schema\Index
,
Doctrine\DBAL\Schema\ForeignKeyConstraint
,
Doctrine\DBAL\Schema\TableDiff
;
/**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
* point of abstraction of platform-specific behaviors, features and SQL dialects.
* They are a passive source of information.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision: 3938 $
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
*/
abstract
class
AbstractPlatform
{
/**
* @var int
*/
const
CREATE_INDEXES
=
1
;
/**
* @var int
*/
const
CREATE_FOREIGNKEYS
=
2
;
/**
* Constructor.
*/
public
function
__construct
()
{}
/**
* Gets the character used for identifier quoting.
*
* @return string
*/
public
function
getIdentifierQuoteCharacter
()
{
return
'"'
;
}
/**
* Gets the string portion that starts an SQL comment.
*
* @return string
*/
public
function
getSqlCommentStartString
()
{
return
"--"
;
}
/**
* Gets the string portion that ends an SQL comment.
*
* @return string
*/
public
function
getSqlCommentEndString
()
{
return
"
\n
"
;
}
/**
* Gets the maximum length of a varchar field.
*
* @return integer
*/
public
function
getVarcharMaxLength
()
{
return
255
;
}
/**
* Gets all SQL wildcard characters of the platform.
*
* @return array
*/
public
function
getWildcards
()
{
return
array
(
'%'
,
'_'
);
}
/**
* Returns the regular expression operator.
*
* @return string
*/
public
function
getRegexpExpression
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Returns the average value of a column
*
* @param string $column the column to use
* @return string generated sql including an AVG aggregate function
*/
public
function
getAvgExpression
(
$column
)
{
return
'AVG('
.
$column
.
')'
;
}
/**
* Returns the number of rows (without a NULL value) of a column
*
* If a '*' is used instead of a column the number of selected rows
* is returned.
*
* @param string|integer $column the column to use
* @return string generated sql including a COUNT aggregate function
*/
public
function
getCountExpression
(
$column
)
{
return
'COUNT('
.
$column
.
')'
;
}
/**
* Returns the highest value of a column
*
* @param string $column the column to use
* @return string generated sql including a MAX aggregate function
*/
public
function
getMaxExpression
(
$column
)
{
return
'MAX('
.
$column
.
')'
;
}
/**
* Returns the lowest value of a column
*
* @param string $column the column to use
* @return string
*/
public
function
getMinExpression
(
$column
)
{
return
'MIN('
.
$column
.
')'
;
}
/**
* Returns the total sum of a column
*
* @param string $column the column to use
* @return string
*/
public
function
getSumExpression
(
$column
)
{
return
'SUM('
.
$column
.
')'
;
}
// scalar functions
/**
* Returns the md5 sum of a field.
*
* Note: Not SQL92, but common functionality
*
* @return string
*/
public
function
getMd5Expression
(
$column
)
{
return
'MD5('
.
$column
.
')'
;
}
/**
* Returns the length of a text field.
*
* @param string $expression1
* @param string $expression2
* @return string
*/
public
function
getLengthExpression
(
$column
)
{
return
'LENGTH('
.
$column
.
')'
;
}
/**
* Rounds a numeric field to the number of decimals specified.
*
* @param string $expression1
* @param string $expression2
* @return string
*/
public
function
getRoundExpression
(
$column
,
$decimals
=
0
)
{
return
'ROUND('
.
$column
.
', '
.
$decimals
.
')'
;
}
/**
* Returns the remainder of the division operation
* $expression1 / $expression2.
*
* @param string $expression1
* @param string $expression2
* @return string
*/
public
function
getModExpression
(
$expression1
,
$expression2
)
{
return
'MOD('
.
$expression1
.
', '
.
$expression2
.
')'
;
}
/**
* trim
* returns the string $str with leading and proceeding space characters removed
*
* @param string $str literal string or column name
* @return string
*/
public
function
getTrimExpression
(
$str
)
{
return
'TRIM('
.
$str
.
')'
;
}
/**
* rtrim
* returns the string $str with proceeding space characters removed
*
* @param string $str literal string or column name
* @return string
*/
public
function
getRtrimExpression
(
$str
)
{
return
'RTRIM('
.
$str
.
')'
;
}
/**
* ltrim
* returns the string $str with leading space characters removed
*
* @param string $str literal string or column name
* @return string
*/
public
function
getLtrimExpression
(
$str
)
{
return
'LTRIM('
.
$str
.
')'
;
}
/**
* upper
* Returns the string $str with all characters changed to
* uppercase according to the current character set mapping.
*
* @param string $str literal string or column name
* @return string
*/
public
function
getUpperExpression
(
$str
)
{
return
'UPPER('
.
$str
.
')'
;
}
/**
* lower
* Returns the string $str with all characters changed to
* lowercase according to the current character set mapping.
*
* @param string $str literal string or column name
* @return string
*/
public
function
getLowerExpression
(
$str
)
{
return
'LOWER('
.
$str
.
')'
;
}
/**
* locate
* returns the position of the first occurrence of substring $substr in string $str
*
* @param string $substr literal string to find
* @param string $str literal string
* @return integer
*/
public
function
getLocateExpression
(
$str
,
$substr
)
{
return
'LOCATE('
.
$str
.
', '
.
$substr
.
')'
;
}
/**
* Returns the current system date.
*
* @return string
*/
public
function
getNowExpression
()
{
return
'NOW()'
;
}
/**
* return string to call a function to get a substring inside an SQL statement
*
* Note: Not SQL92, but common functionality.
*
* SQLite only supports the 2 parameter variant of this function
*
* @param string $value an sql string literal or column name/alias
* @param integer $position where to start the substring portion
* @param integer $length the substring portion length
* @return string SQL substring function with given parameters
*/
public
function
getSubstringExpression
(
$value
,
$from
,
$len
=
null
)
{
if
(
$len
===
null
)
return
'SUBSTRING('
.
$value
.
' FROM '
.
$from
.
')'
;
else
{
return
'SUBSTRING('
.
$value
.
' FROM '
.
$from
.
' FOR '
.
$len
.
')'
;
}
}
/**
* Returns a series of strings concatinated
*
* concat() accepts an arbitrary number of parameters. Each parameter
* must contain an expression
*
* @param string $arg1, $arg2 ... $argN strings that will be concatinated.
* @return string
*/
public
function
getConcatExpression
()
{
return
join
(
' || '
,
func_get_args
());
}
/**
* Returns the SQL for a logical not.
*
* Example:
* <code>
* $q = new Doctrine_Query();
* $e = $q->expr;
* $q->select('*')->from('table')
* ->where($e->eq('id', $e->not('null'));
* </code>
*
* @return string a logical expression
*/
public
function
getNotExpression
(
$expression
)
{
return
'NOT('
.
$expression
.
')'
;
}
/**
* Returns the SQL to check if a value is one in a set of
* given values.
*
* in() accepts an arbitrary number of parameters. The first parameter
* must always specify the value that should be matched against. Successive
* must contain a logical expression or an array with logical expressions.
* These expressions will be matched against the first parameter.
*
* @param string $column the value that should be matched against
* @param string|array(string) values that will be matched against $column
* @return string logical expression
*/
public
function
getInExpression
(
$column
,
$values
)
{
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
}
$values
=
$this
->
getIdentifiers
(
$values
);
if
(
count
(
$values
)
==
0
)
{
throw
\InvalidArgumentException
(
'Values must not be empty.'
);
}
return
$column
.
' IN ('
.
implode
(
', '
,
$values
)
.
')'
;
}
/**
* Returns SQL that checks if a expression is null.
*
* @param string $expression the expression that should be compared to null
* @return string logical expression
*/
public
function
getIsNullExpression
(
$expression
)
{
return
$expression
.
' IS NULL'
;
}
/**
* Returns SQL that checks if a expression is not null.
*
* @param string $expression the expression that should be compared to null
* @return string logical expression
*/
public
function
getIsNotNullExpression
(
$expression
)
{
return
$expression
.
' IS NOT NULL'
;
}
/**
* Returns SQL that checks if an expression evaluates to a value between
* two values.
*
* The parameter $expression is checked if it is between $value1 and $value2.
*
* Note: There is a slight difference in the way BETWEEN works on some databases.
* http://www.w3schools.com/sql/sql_between.asp. If you want complete database
* independence you should avoid using between().
*
* @param string $expression the value to compare to
* @param string $value1 the lower value to compare with
* @param string $value2 the higher value to compare with
* @return string logical expression
*/
public
function
getBetweenExpression
(
$expression
,
$value1
,
$value2
)
{
return
$expression
.
' BETWEEN '
.
$value1
.
' AND '
.
$value2
;
}
public
function
getAcosExpression
(
$value
)
{
return
'ACOS('
.
$value
.
')'
;
}
public
function
getSinExpression
(
$value
)
{
return
'SIN('
.
$value
.
')'
;
}
public
function
getPiExpression
()
{
return
'PI()'
;
}
public
function
getCosExpression
(
$value
)
{
return
'COS('
.
$value
.
')'
;
}
public
function
getForUpdateSql
()
{
return
'FOR UPDATE'
;
}
public
function
getDropDatabaseSql
(
$database
)
{
return
'DROP DATABASE '
.
$database
;
}
/**
* Drop a Table
*
* @param Table|string $table
* @return string
*/
public
function
getDropTableSql
(
$table
)
{
if
(
$table
instanceof
\Doctrine\DBAL\Schema\Table
)
{
$table
=
$table
->
getName
();
}
return
'DROP TABLE '
.
$table
;
}
/**
* Drop index from a table
*
* @param Index|string $name
* @param string|Table $table
* @return string
*/
public
function
getDropIndexSql
(
$index
,
$table
=
null
)
{
if
(
$index
instanceof
\Doctrine\DBAL\Schema\Index
)
{
$index
=
$index
->
getName
();
}
else
if
(
!
is_string
(
$index
))
{
throw
new
\InvalidArgumentException
(
'AbstractPlatform::getDropIndexSql() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'
);
}
return
'DROP INDEX '
.
$index
;
}
/**
* Get drop constraint sql
*
* @param \Doctrine\DBAL\Schema\Constraint $constraint
* @param string|Table $table
* @return string
*/
public
function
getDropConstraintSql
(
$constraint
,
$table
)
{
if
(
$constraint
instanceof
\Doctrine\DBAL\Schema\Constraint
)
{
$constraint
=
$constraint
->
getName
();
}
if
(
$table
instanceof
\Doctrine\DBAL\Schema\Table
)
{
$table
=
$table
->
getName
();
}
return
'ALTER TABLE '
.
$table
.
' DROP CONSTRAINT '
.
$constraint
;
}
/**
* @param ForeignKeyConstraint|string $foreignKey
* @param Table|string $table
* @return string
*/
public
function
getDropForeignKeySql
(
$foreignKey
,
$table
)
{
if
(
$foreignKey
instanceof
\Doctrine\DBAL\Schema\ForeignKeyConstraint
)
{
$foreignKey
=
$foreignKey
->
getName
();
}
if
(
$table
instanceof
\Doctrine\DBAL\Schema\Table
)
{
$table
=
$table
->
getName
();
}
return
'ALTER TABLE '
.
$table
.
' DROP FOREIGN KEY '
.
$foreignKey
;
}
/**
* Gets the SQL statement(s) to create a table with the specified name, columns and constraints
* on this platform.
*
* @param string $table The name of the table.
* @param int $createFlags
* @return array The sequence of SQL statements.
*/
public
function
getCreateTableSql
(
Table
$table
,
$createFlags
=
self
::
CREATE_INDEXES
)
{
if
(
!
is_int
(
$createFlags
))
{
throw
new
\InvalidArgumentException
(
"Second argument of AbstractPlatform::getCreateTableSql() has to be integer."
);
}
$tableName
=
$table
->
getName
();
$options
=
$table
->
getOptions
();
$options
[
'uniqueConstraints'
]
=
array
();
$options
[
'indexes'
]
=
array
();
$options
[
'primary'
]
=
array
();
if
((
$createFlags
&
self
::
CREATE_INDEXES
)
>
0
)
{
foreach
(
$table
->
getIndexes
()
AS
$index
)
{
/* @var $index Index */
if
(
$index
->
isPrimary
())
{
$options
[
'primary'
]
=
$index
->
getColumns
();
}
else
{
$options
[
'indexes'
][
$index
->
getName
()]
=
$index
;
}
}
}
$columns
=
array
();
foreach
(
$table
->
getColumns
()
AS
$column
)
{
/* @var \Doctrine\DBAL\Schema\Column $column */
$columnData
=
array
();
$columnData
[
'name'
]
=
$column
->
getName
();
$columnData
[
'type'
]
=
$column
->
getType
();
$columnData
[
'length'
]
=
$column
->
getLength
();
$columnData
[
'notnull'
]
=
$column
->
getNotNull
();
$columnData
[
'unique'
]
=
(
$column
->
hasPlatformOption
(
"unique"
))
?
$column
->
getPlatformOption
(
'unique'
)
:
false
;
$columnData
[
'version'
]
=
(
$column
->
hasPlatformOption
(
"version"
))
?
$column
->
getPlatformOption
(
'version'
)
:
false
;
if
(
strtolower
(
$columnData
[
'type'
])
==
"string"
&&
$columnData
[
'length'
]
===
null
)
{
$columnData
[
'length'
]
=
255
;
}
$columnData
[
'precision'
]
=
$column
->
getPrecision
();
$columnData
[
'scale'
]
=
$column
->
getScale
();
$columnData
[
'default'
]
=
$column
->
getDefault
();
// TODO: Fixed? Unsigned?
if
(
in_array
(
$column
->
getName
(),
$options
[
'primary'
]))
{
$columnData
[
'primary'
]
=
true
;
if
(
$table
->
isIdGeneratorIdentity
())
{
$columnData
[
'autoincrement'
]
=
true
;
}
}
$columns
[
$columnData
[
'name'
]]
=
$columnData
;
}
if
((
$createFlags
&
self
::
CREATE_FOREIGNKEYS
)
>
0
)
{
$options
[
'foreignKeys'
]
=
array
();
foreach
(
$table
->
getForeignKeys
()
AS
$fkConstraint
)
{
$options
[
'foreignKeys'
][]
=
$fkConstraint
;
}
}
return
$this
->
_getCreateTableSql
(
$tableName
,
$columns
,
$options
);
}
/**
* @param string $tableName
* @param array $columns
* @param array $options
* @return array
*/
protected
function
_getCreateTableSql
(
$tableName
,
array
$columns
,
array
$options
=
array
())
{
$columnListSql
=
$this
->
getColumnDeclarationListSql
(
$columns
);
if
(
isset
(
$options
[
'uniqueConstraints'
])
&&
!
empty
(
$options
[
'uniqueConstraints'
]))
{
foreach
(
$options
[
'uniqueConstraints'
]
as
$name
=>
$definition
)
{
$columnListSql
.=
', '
.
$this
->
getUniqueConstraintDeclarationSql
(
$name
,
$definition
);
}
}
if
(
isset
(
$options
[
'primary'
])
&&
!
empty
(
$options
[
'primary'
]))
{
$columnListSql
.=
', PRIMARY KEY('
.
implode
(
', '
,
array_unique
(
array_values
(
$options
[
'primary'
])))
.
')'
;
}
if
(
isset
(
$options
[
'indexes'
])
&&
!
empty
(
$options
[
'indexes'
]))
{
foreach
(
$options
[
'indexes'
]
as
$index
=>
$definition
)
{
$columnListSql
.=
', '
.
$this
->
getIndexDeclarationSql
(
$index
,
$definition
);
}
}
$query
=
'CREATE TABLE '
.
$tableName
.
' ('
.
$columnListSql
;
$check
=
$this
->
getCheckDeclarationSql
(
$columns
);
if
(
!
empty
(
$check
))
{
$query
.=
', '
.
$check
;
}
$query
.=
')'
;
$sql
[]
=
$query
;
if
(
isset
(
$options
[
'foreignKeys'
]))
{
foreach
((
array
)
$options
[
'foreignKeys'
]
AS
$definition
)
{
$sql
[]
=
$this
->
getCreateForeignKeySql
(
$definition
,
$tableName
);
}
}
return
$sql
;
}
public
function
getCreateTemporaryTableSnippetSql
()
{
return
"CREATE TEMPORARY TABLE"
;
}
/**
* Gets the SQL to create a sequence on this platform.
*
* @param \Doctrine\DBAL\Schema\Sequence $sequence
* @throws DoctrineException
*/
public
function
getCreateSequenceSql
(
\Doctrine\DBAL\Schema\Sequence
$sequence
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Gets the SQL to create a constraint on a table on this platform.
*
* @param Constraint $constraint
* @param string|Table $table
* @return string
*/
public
function
getCreateConstraintSql
(
\Doctrine\DBAL\Schema\Constraint
$constraint
,
$table
)
{
if
(
$table
instanceof
\Doctrine\DBAL\Schema\Table
)
{
$table
=
$table
->
getName
();
}
$query
=
'ALTER TABLE '
.
$table
.
' ADD CONSTRAINT '
.
$constraint
->
getName
();
$columns
=
array
();
foreach
(
$constraint
->
getColumns
()
as
$column
)
{
$columns
[]
=
$column
;
}
$columnList
=
'('
.
implode
(
', '
,
$columns
)
.
')'
;
$referencesClause
=
''
;
if
(
$constraint
instanceof
\Doctrine\DBAL\Schema\Index
)
{
if
(
$constraint
->
isPrimary
())
{
$query
.=
' PRIMARY KEY'
;
}
elseif
(
$constraint
->
isUnique
())
{
$query
.=
' UNIQUE'
;
}
else
{
throw
new
\InvalidArgumentException
(
'Can only create primary or unique constraints, no common indexes with getCreateConstraintSql().'
);
}
}
else
if
(
$constraint
instanceof
\Doctrine\DBAL\Schema\ForeignKeyConstraint
)
{
$query
.=
' FOREIGN KEY'
;
$foreignColumns
=
array
();
foreach
(
$constraint
->
getForeignColumns
()
AS
$column
)
{
$foreignColumns
[]
=
$column
;
}
$referencesClause
=
' REFERENCES '
.
$constraint
->
getForeignTableName
()
.
' ('
.
implode
(
', '
,
$foreignColumns
)
.
')'
;
}
$query
.=
' '
.
$columnList
.
$referencesClause
;
return
$query
;
}
/**
* Gets the SQL to create an index on a table on this platform.
*
* @param Index $index
* @param string|Table $table name of the table on which the index is to be created
* @return string
*/
public
function
getCreateIndexSql
(
Index
$index
,
$table
)
{
if
(
$table
instanceof
Table
)
{
$table
=
$table
->
getName
();
}
$name
=
$index
->
getName
();
$columns
=
$index
->
getColumns
();
if
(
count
(
$columns
)
==
0
)
{
throw
new
\InvalidArgumentException
(
"Incomplete definition. 'columns' required."
);
}
$type
=
''
;
if
(
$index
->
isUnique
())
{
$type
=
'UNIQUE '
;
}
$query
=
'CREATE '
.
$type
.
'INDEX '
.
$name
.
' ON '
.
$table
;
$query
.=
' ('
.
$this
->
getIndexFieldDeclarationListSql
(
$columns
)
.
')'
;
return
$query
;
}
/**
* Quotes a string so that it can be safely used as a table or column name,
* even if it is a reserved word of the platform.
*
* NOTE: Just because you CAN use quoted identifiers doesn't mean
* you SHOULD use them. In general, they end up causing way more
* problems than they solve.
*
* @param string $str identifier name to be quoted
* @return string quoted identifier string
*/
public
function
quoteIdentifier
(
$str
)
{
$c
=
$this
->
getIdentifierQuoteCharacter
();
return
$c
.
$str
.
$c
;
}
/**
* Create a new foreign key
*
* @param ForeignKeyConstraint $foreignKey ForeignKey instance
* @param string|Table $table name of the table on which the foreign key is to be created
* @return string
*/
public
function
getCreateForeignKeySql
(
ForeignKeyConstraint
$foreignKey
,
$table
)
{
if
(
$table
instanceof
\Doctrine\DBAL\Schema\Table
)
{
$table
=
$table
->
getName
();
}
$query
=
'ALTER TABLE '
.
$table
.
' ADD '
.
$this
->
getForeignKeyDeclarationSql
(
$foreignKey
);
return
$query
;
}
/**
* Gets the sql statements for altering an existing table.
*
* The method returns an array of sql statements, since some platforms need several statements.
*
* @param TableDiff $diff
* @return array
*/
public
function
getAlterTableSql
(
TableDiff
$diff
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
*
* @param TableDiff $diff
* @return array
*/
protected
function
_getAlterTableIndexForeignKeySql
(
TableDiff
$diff
)
{
if
(
$diff
->
newName
!==
false
)
{
$tableName
=
$diff
->
newName
;
}
else
{
$tableName
=
$diff
->
name
;
}
$sql
=
array
();
if
(
$this
->
supportsForeignKeyConstraints
())
{
foreach
(
$diff
->
addedForeignKeys
AS
$foreignKey
)
{
$sql
[]
=
$this
->
getCreateForeignKeySql
(
$foreignKey
,
$tableName
);
}
foreach
(
$diff
->
removedForeignKeys
AS
$foreignKey
)
{
$sql
[]
=
$this
->
getDropForeignKeySql
(
$foreignKey
,
$tableName
);
}
foreach
(
$diff
->
changedForeignKeys
AS
$foreignKey
)
{
$sql
[]
=
$this
->
getDropForeignKeySql
(
$foreignKey
,
$tableName
);
$sql
[]
=
$this
->
getCreateForeignKeySql
(
$foreignKey
,
$tableName
);
}
}
foreach
(
$diff
->
addedIndexes
AS
$index
)
{
$sql
[]
=
$this
->
getCreateIndexSql
(
$index
,
$tableName
);
}
foreach
(
$diff
->
removedIndexes
AS
$index
)
{
$sql
[]
=
$this
->
getDropIndexSql
(
$index
,
$tableName
);
}
foreach
(
$diff
->
changedIndexes
AS
$index
)
{
$sql
[]
=
$this
->
getDropIndexSql
(
$index
,
$tableName
);
$sql
[]
=
$this
->
getCreateIndexSql
(
$index
,
$tableName
);
}
return
$sql
;
}
/**
* Get declaration of a number of fields in bulk
*
* @param array $fields a multidimensional associative array.
* The first dimension determines the field name, while the second
* dimension is keyed with the name of the properties
* of the field being declared as array indexes. Currently, the types
* of supported field properties are as follows:
*
* length
* Integer value that determines the maximum length of the text
* field. If this argument is missing the field should be
* declared to have the longest length allowed by the DBMS.
*
* default
* Text value to be used as default for this field.
*
* notnull
* Boolean flag that indicates whether this field is constrained
* to not be set to null.
* charset
* Text value with the default CHARACTER SET for this field.
* collation
* Text value with the default COLLATION for this field.
* unique
* unique constraint
*
* @return string
*/
public
function
getColumnDeclarationListSql
(
array
$fields
)
{
$queryFields
=
array
();
foreach
(
$fields
as
$fieldName
=>
$field
)
{
$query
=
$this
->
getColumnDeclarationSql
(
$fieldName
,
$field
);
$queryFields
[]
=
$query
;
}
return
implode
(
', '
,
$queryFields
);
}
/**
* Obtain DBMS specific SQL code portion needed to declare a generic type
* field to be used in statements like CREATE TABLE.
*
* @param string $name name the field to be declared.
* @param array $field associative array with the name of the properties
* of the field being declared as array indexes. Currently, the types
* of supported field properties are as follows:
*
* length
* Integer value that determines the maximum length of the text
* field. If this argument is missing the field should be
* declared to have the longest length allowed by the DBMS.
*
* default
* Text value to be used as default for this field.
*
* notnull
* Boolean flag that indicates whether this field is constrained
* to not be set to null.
* charset
* Text value with the default CHARACTER SET for this field.
* collation
* Text value with the default COLLATION for this field.
* unique
* unique constraint
* check
* column check constraint
*
* @return string DBMS specific SQL code portion that should be used to declare the column.
*/
public
function
getColumnDeclarationSql
(
$name
,
array
$field
)
{
$default
=
$this
->
getDefaultValueDeclarationSql
(
$field
);
$charset
=
(
isset
(
$field
[
'charset'
])
&&
$field
[
'charset'
])
?
' '
.
$this
->
getColumnCharsetDeclarationSql
(
$field
[
'charset'
])
:
''
;
$collation
=
(
isset
(
$field
[
'collation'
])
&&
$field
[
'collation'
])
?
' '
.
$this
->
getColumnCollationDeclarationSql
(
$field
[
'collation'
])
:
''
;
$notnull
=
(
isset
(
$field
[
'notnull'
])
&&
$field
[
'notnull'
])
?
' NOT NULL'
:
''
;
$unique
=
(
isset
(
$field
[
'unique'
])
&&
$field
[
'unique'
])
?
' '
.
$this
->
getUniqueFieldDeclarationSql
()
:
''
;
$check
=
(
isset
(
$field
[
'check'
])
&&
$field
[
'check'
])
?
' '
.
$field
[
'check'
]
:
''
;
$typeDecl
=
$field
[
'type'
]
->
getSqlDeclaration
(
$field
,
$this
);
return
$name
.
' '
.
$typeDecl
.
$charset
.
$default
.
$notnull
.
$unique
.
$check
.
$collation
;
}
/**
* Gets the SQL snippet that declares a floating point column of arbitrary precision.
*
* @param array $columnDef
* @return string
*/
public
function
getDecimalTypeDeclarationSql
(
array
$columnDef
)
{
$columnDef
[
'precision'
]
=
(
!
isset
(
$columnDef
[
'precision'
])
||
empty
(
$columnDef
[
'precision'
]))
?
10
:
$columnDef
[
'precision'
];
$columnDef
[
'scale'
]
=
(
!
isset
(
$columnDef
[
'scale'
])
||
empty
(
$columnDef
[
'scale'
]))
?
0
:
$columnDef
[
'scale'
];
return
'NUMERIC('
.
$columnDef
[
'precision'
]
.
', '
.
$columnDef
[
'scale'
]
.
')'
;
}
/**
* Gets the SQL snippet that declares a boolean column.
*
* @param array $columnDef
* @return string
*/
abstract
public
function
getBooleanTypeDeclarationSql
(
array
$columnDef
);
/**
* Gets the SQL snippet that declares a 4 byte integer column.
*
* @param array $columnDef
* @return string
*/
abstract
public
function
getIntegerTypeDeclarationSql
(
array
$columnDef
);
/**
* Gets the SQL snippet that declares an 8 byte integer column.
*
* @param array $columnDef
* @return string
*/
abstract
public
function
getBigIntTypeDeclarationSql
(
array
$columnDef
);
/**
* Gets the SQL snippet that declares a 2 byte integer column.
*
* @param array $columnDef
* @return string
*/
abstract
public
function
getSmallIntTypeDeclarationSql
(
array
$columnDef
);
/**
* Gets the SQL snippet that declares common properties of an integer column.
*
* @param array $columnDef
* @return string
*/
abstract
protected
function
_getCommonIntegerTypeDeclarationSql
(
array
$columnDef
);
/**
* Obtain DBMS specific SQL code portion needed to set a default value
* declaration to be used in statements like CREATE TABLE.
*
* @param array $field field definition array
* @return string DBMS specific SQL code portion needed to set a default value
*/
public
function
getDefaultValueDeclarationSql
(
$field
)
{
$default
=
empty
(
$field
[
'notnull'
])
?
' DEFAULT NULL'
:
''
;
if
(
isset
(
$field
[
'default'
]))
{
$default
=
" DEFAULT '"
.
$field
[
'default'
]
.
"'"
;
if
(
isset
(
$field
[
'type'
]))
{
if
(
in_array
((
string
)
$field
[
'type'
],
array
(
"Integer"
,
"BigInteger"
,
"SmallInteger"
)))
{
$default
=
" DEFAULT "
.
$field
[
'default'
];
}
else
if
((
string
)
$field
[
'type'
]
==
'DateTime'
&&
$field
[
'default'
]
==
$this
->
getCurrentTimestampSql
())
{
$default
=
" DEFAULT "
.
$this
->
getCurrentTimestampSql
();
}
}
}
return
$default
;
}
/**
* Obtain DBMS specific SQL code portion needed to set a CHECK constraint
* declaration to be used in statements like CREATE TABLE.
*
* @param array $definition check definition
* @return string DBMS specific SQL code portion needed to set a CHECK constraint
*/
public
function
getCheckDeclarationSql
(
array
$definition
)
{
$constraints
=
array
();
foreach
(
$definition
as
$field
=>
$def
)
{
if
(
is_string
(
$def
))
{
$constraints
[]
=
'CHECK ('
.
$def
.
')'
;
}
else
{
if
(
isset
(
$def
[
'min'
]))
{
$constraints
[]
=
'CHECK ('
.
$field
.
' >= '
.
$def
[
'min'
]
.
')'
;
}
if
(
isset
(
$def
[
'max'
]))
{
$constraints
[]
=
'CHECK ('
.
$field
.
' <= '
.
$def
[
'max'
]
.
')'
;
}
}
}
return
implode
(
', '
,
$constraints
);
}
/**
* Obtain DBMS specific SQL code portion needed to set a unique
* constraint declaration to be used in statements like CREATE TABLE.
*
* @param string $name name of the unique constraint
* @param Index $index index definition
* @return string DBMS specific SQL code portion needed
* to set a constraint
*/
public
function
getUniqueConstraintDeclarationSql
(
$name
,
Index
$index
)
{
if
(
count
(
$index
->
getColumns
())
==
0
)
{
throw
\InvalidArgumentException
(
"Incomplete definition. 'columns' required."
);
}
return
'CONSTRAINT'
.
$name
.
' UNIQUE ('
.
$this
->
getIndexFieldDeclarationListSql
(
$index
->
getColumns
())
.
')'
;
}
/**
* Obtain DBMS specific SQL code portion needed to set an index
* declaration to be used in statements like CREATE TABLE.
*
* @param string $name name of the index
* @param Index $index index definition
* @return string DBMS specific SQL code portion needed to set an index
*/
public
function
getIndexDeclarationSql
(
$name
,
Index
$index
)
{
$type
=
''
;
if
(
$index
->
isUnique
())
{
$type
=
'UNIQUE '
;
}
if
(
count
(
$index
->
getColumns
())
==
0
)
{
throw
\InvalidArgumentException
(
"Incomplete definition. 'columns' required."
);
}
return
$type
.
'INDEX '
.
$name
.
' ('
.
$this
->
getIndexFieldDeclarationListSql
(
$index
->
getColumns
())
.
')'
;
}
/**
* getIndexFieldDeclarationList
* Obtain DBMS specific SQL code portion needed to set an index
* declaration to be used in statements like CREATE TABLE.
*
* @return string
*/
public
function
getIndexFieldDeclarationListSql
(
array
$fields
)
{
$ret
=
array
();
foreach
(
$fields
as
$field
=>
$definition
)
{
if
(
is_array
(
$definition
))
{
$ret
[]
=
$field
;
}
else
{
$ret
[]
=
$definition
;
}
}
return
implode
(
', '
,
$ret
);
}
/**
* A method to return the required SQL string that fits between CREATE ... TABLE
* to create the table as a temporary table.
*
* Should be overridden in driver classes to return the correct string for the
* specific database type.
*
* The default is to return the string "TEMPORARY" - this will result in a
* SQL error for any database that does not support temporary tables, or that
* requires a different SQL command from "CREATE TEMPORARY TABLE".
*
* @return string The string required to be placed between "CREATE" and "TABLE"
* to generate a temporary table, if possible.
*/
public
function
getTemporaryTableSql
()
{
return
'TEMPORARY'
;
}
/**
* Get sql query to show a list of database
*
* @return unknown
*/
public
function
getShowDatabasesSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* getForeignKeyDeclaration
* Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param array $definition an associative array with the following structure:
* name optional constraint name
*
* local the local field(s)
*
* foreign the foreign reference field(s)
*
* foreignTable the name of the foreign table
*
* onDelete referential delete action
*
* onUpdate referential update action
*
* deferred deferred constraint checking
*
* The onDelete and onUpdate keys accept the following values:
*
* CASCADE: Delete or update the row from the parent table and automatically delete or
* update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
* Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column
* in the parent table or in the child table.
*
* SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the
* child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier
* specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
*
* NO ACTION: In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary
* key value is not allowed to proceed if there is a related foreign key value in the referenced table.
*
* RESTRICT: Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as
* omitting the ON DELETE or ON UPDATE clause.
*
* SET DEFAULT
*
* @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
* of a field declaration.
*/
public
function
getForeignKeyDeclarationSql
(
ForeignKeyConstraint
$foreignKey
)
{
$sql
=
$this
->
getForeignKeyBaseDeclarationSql
(
$foreignKey
);
$sql
.=
$this
->
getAdvancedForeignKeyOptionsSql
(
$foreignKey
);
return
$sql
;
}
/**
* Return the FOREIGN KEY query section dealing with non-standard options
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
*
* @param ForeignKeyConstraint $foreignKey foreign key definition
* @return string
*/
public
function
getAdvancedForeignKeyOptionsSql
(
ForeignKeyConstraint
$foreignKey
)
{
$query
=
''
;
if
(
$this
->
supportsForeignKeyOnUpdate
()
&&
$foreignKey
->
hasOption
(
'onUpdate'
))
{
$query
.=
' ON UPDATE '
.
$this
->
getForeignKeyReferentialActionSql
(
$foreignKey
->
getOption
(
'onUpdate'
));
}
if
(
$foreignKey
->
hasOption
(
'onDelete'
))
{
$query
.=
' ON DELETE '
.
$this
->
getForeignKeyReferentialActionSql
(
$foreignKey
->
getOption
(
'onDelete'
));
}
return
$query
;
}
/**
* returns given referential action in uppercase if valid, otherwise throws
* an exception
*
* @throws Doctrine_Exception_Exception if unknown referential action given
* @param string $action foreign key referential action
* @param string foreign key referential action in uppercase
*/
public
function
getForeignKeyReferentialActionSql
(
$action
)
{
$upper
=
strtoupper
(
$action
);
switch
(
$upper
)
{
case
'CASCADE'
:
case
'SET NULL'
:
case
'NO ACTION'
:
case
'RESTRICT'
:
case
'SET DEFAULT'
:
return
$upper
;
break
;
default
:
throw
\InvalidArgumentException
(
'Invalid foreign key action: '
.
$upper
);
}
}
/**
* Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param ForeignKeyConstraint $foreignKey
* @return string
*/
public
function
getForeignKeyBaseDeclarationSql
(
ForeignKeyConstraint
$foreignKey
)
{
$sql
=
''
;
if
(
strlen
(
$foreignKey
->
getName
()))
{
$sql
.=
'CONSTRAINT '
.
$foreignKey
->
getName
()
.
' '
;
}
$sql
.=
'FOREIGN KEY ('
;
if
(
count
(
$foreignKey
->
getLocalColumns
())
==
0
)
{
throw
new
\InvalidArgumentException
(
"Incomplete definition. 'local' required."
);
}
if
(
count
(
$foreignKey
->
getForeignColumns
())
==
0
)
{
throw
new
\InvalidArgumentException
(
"Incomplete definition. 'foreign' required."
);
}
if
(
strlen
(
$foreignKey
->
getForeignTableName
())
==
0
)
{
throw
new
\InvalidArgumentException
(
"Incomplete definition. 'foreignTable' required."
);
}
$sql
.=
implode
(
', '
,
$foreignKey
->
getLocalColumns
())
.
') REFERENCES '
.
$foreignKey
->
getForeignTableName
()
.
'('
.
implode
(
', '
,
$foreignKey
->
getForeignColumns
())
.
')'
;
return
$sql
;
}
/**
* Obtain DBMS specific SQL code portion needed to set the UNIQUE constraint
* of a field declaration to be used in statements like CREATE TABLE.
*
* @return string DBMS specific SQL code portion needed to set the UNIQUE constraint
* of a field declaration.
*/
public
function
getUniqueFieldDeclarationSql
()
{
return
'UNIQUE'
;
}
/**
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param string $charset name of the charset
* @return string DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration.
*/
public
function
getColumnCharsetDeclarationSql
(
$charset
)
{
return
''
;
}
/**
* Obtain DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param string $collation name of the collation
* @return string DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration.
*/
public
function
getColumnCollationDeclarationSql
(
$collation
)
{
return
''
;
}
/**
* build a pattern matching string
*
* EXPERIMENTAL
*
* WARNING: this function is experimental and may change signature at
* any time until labelled as non-experimental
*
* @access public
*
* @param array $pattern even keys are strings, odd are patterns (% and _)
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
* @param string $field optional field name that is being matched against
* (might be required when emulating ILIKE)
*
* @return string SQL pattern
*/
public
function
getMatchPatternExpression
(
$pattern
,
$operator
=
null
,
$field
=
null
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Whether the platform prefers sequences for ID generation.
* Subclasses should override this method to return TRUE if they prefer sequences.
*
* @return boolean
*/
public
function
prefersSequences
()
{
return
false
;
}
/**
* Whether the platform prefers identity columns (eg. autoincrement) for ID generation.
* Subclasses should override this method to return TRUE if they prefer identity columns.
*
* @return boolean
*/
public
function
prefersIdentityColumns
()
{
return
false
;
}
/**
* Some platforms need the boolean values to be converted.
*
* The default conversion in this implementation converts to integers (false => 0, true => 1).
*
* @param mixed $item
*/
public
function
convertBooleans
(
$item
)
{
if
(
is_array
(
$item
))
{
foreach
(
$item
as
$k
=>
$value
)
{
if
(
is_bool
(
$value
))
{
$item
[
$k
]
=
(
int
)
$value
;
}
}
}
else
if
(
is_bool
(
$item
))
{
$item
=
(
int
)
$item
;
}
return
$item
;
}
/**
* Gets the SQL statement specific for the platform to set the charset.
*
* This function is MySQL specific and required by
* {@see \Doctrine\DBAL\Connection::setCharset($charset)}
*
* @param string $charset
* @return string
*/
public
function
getSetCharsetSql
(
$charset
)
{
return
"SET NAMES '"
.
$charset
.
"'"
;
}
/**
* Gets the SQL specific for the platform to get the current date.
*
* @return string
*/
public
function
getCurrentDateSql
()
{
return
'CURRENT_DATE'
;
}
/**
* Gets the SQL specific for the platform to get the current time.
*
* @return string
*/
public
function
getCurrentTimeSql
()
{
return
'CURRENT_TIME'
;
}
/**
* Gets the SQL specific for the platform to get the current timestamp
*
* @return string
*/
public
function
getCurrentTimestampSql
()
{
return
'CURRENT_TIMESTAMP'
;
}
/**
* Get sql for transaction isolation level Connection constant
*
* @param integer $level
*/
protected
function
_getTransactionIsolationLevelSql
(
$level
)
{
switch
(
$level
)
{
case
Connection
::
TRANSACTION_READ_UNCOMMITTED
:
return
'READ UNCOMMITTED'
;
case
Connection
::
TRANSACTION_READ_COMMITTED
:
return
'READ COMMITTED'
;
case
Connection
::
TRANSACTION_REPEATABLE_READ
:
return
'REPEATABLE READ'
;
case
Connection
::
TRANSACTION_SERIALIZABLE
:
return
'SERIALIZABLE'
;
default
:
throw
new
\InvalidArgumentException
(
'Invalid isolation level:'
.
$level
);
}
}
public
function
getListDatabasesSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListFunctionsSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTriggersSql
(
$table
=
null
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListSequencesSql
(
$database
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTableConstraintsSql
(
$table
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTableColumnsSql
(
$table
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTablesSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListUsersSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListViewsSql
()
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTableIndexesSql
(
$table
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getListTableForeignKeysSql
(
$table
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getCreateViewSql
(
$name
,
$sql
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getDropViewSql
(
$name
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getDropSequenceSql
(
$sequence
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getSequenceNextValSql
(
$sequenceName
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
public
function
getCreateDatabaseSql
(
$database
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Get sql to set the transaction isolation level
*
* @param integer $level
*/
public
function
getSetTransactionIsolationSql
(
$level
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param string $charset name of the charset
* @return string DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration.
*/
public
function
getCharsetFieldDeclaration
(
$charset
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Obtain DBMS specific SQL to be used to create datetime fields in
* statements like CREATE TABLE
*
* @param array $fieldDeclaration
* @return string
*/
public
function
getDateTimeTypeDeclarationSql
(
array
$fieldDeclaration
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Obtain DBMS specific SQL to be used to create date fields in statements
* like CREATE TABLE.
*
* @param array $fieldDeclaration
* @return string
*/
public
function
getDateTypeDeclarationSql
(
array
$fieldDeclaration
)
{
throw
DBALException
::
notSupported
(
__METHOD__
);
}
/**
* Obtain DBMS specific SQL to be used to create time fields in statements
* like CREATE TABLE.
*
* @param array $fieldDeclaration
* @return string
*/
public
function
getTimeTypeDeclarationSql
(
array
$fieldDeclaration
)
{
throw
DoctrineException
::
getTimeTypeDeclarationNotSupported
(
$this
);
}
/**
* Gets the default transaction isolation level of the platform.
*
* @return integer The default isolation level.
* @see Doctrine\DBAL\Connection\TRANSACTION_* constants.
*/
public
function
getDefaultTransactionIsolationLevel
()
{
return
Connection
::
TRANSACTION_READ_COMMITTED
;
}
/* supports*() metods */
/**
* Whether the platform supports sequences.
*
* @return boolean
*/
public
function
supportsSequences
()
{
return
false
;
}
/**
* Whether the platform supports identity columns.
* Identity columns are columns that recieve an auto-generated value from the
* database on insert of a row.
*
* @return boolean
*/
public
function
supportsIdentityColumns
()
{
return
false
;
}
/**
* Whether the platform supports indexes.
*
* @return boolean
*/
public
function
supportsIndexes
()
{
return
true
;
}
public
function
supportsAlterTable
()
{
return
true
;
}
/**
* Whether the platform supports transactions.
*
* @return boolean
*/
public
function
supportsTransactions
()
{
return
true
;
}
/**
* Whether the platform supports savepoints.
*
* @return boolean
*/
public
function
supportsSavepoints
()
{
return
true
;
}
/**
* Whether the platform supports primary key constraints.
*
* @return boolean
*/
public
function
supportsPrimaryConstraints
()
{
return
true
;
}
/**
* Does the platform supports foreign key constraints?
*
* @return boolean
*/
public
function
supportsForeignKeyConstraints
()
{
return
true
;
}
/**
* Does this platform supports onUpdate in foreign key constraints?
*
* @return bool
*/
public
function
supportsForeignKeyOnUpdate
()
{
return
(
$this
->
supportsForeignKeyConstraints
()
&&
true
);
}
/**
* Whether the platform supports database schemas.
*
* @return boolean
*/
public
function
supportsSchemas
()
{
return
false
;
}
/**
* @return bool
*/
public
function
createsExplicitIndexForForeignKeys
()
{
return
false
;
}
/**
* Whether the platform supports getting the affected rows of a recent
* update/delete type query.
*
* @return boolean
*/
public
function
supportsGettingAffectedRows
()
{
return
true
;
}
public
function
getIdentityColumnNullInsertSql
()
{
return
""
;
}
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored datetime value of this platform.
*
* @return string The format string.
*
* @todo We need to get the specific format for each dbms and override this
* function for each platform
*/
public
function
getDateTimeFormatString
()
{
return
'Y-m-d H:i:s'
;
}
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored date value of this platform.
*
* @return string The format string.
*/
public
function
getDateFormatString
()
{
return
'Y-m-d'
;
}
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored time value of this platform.
*
* @return string The format string.
*/
public
function
getTimeFormatString
()
{
return
'H:i:s'
;
}
public
function
modifyLimitQuery
(
$query
,
$limit
,
$offset
=
null
)
{
if
(
!
is_null
(
$limit
))
{
$query
.=
' LIMIT '
.
$limit
;
}
if
(
!
is_null
(
$offset
))
{
$query
.=
' OFFSET '
.
$offset
;
}
return
$query
;
}
/**
* Gets the SQL snippet used to declare a VARCHAR column type.
*
* @param array $field
*/
abstract
public
function
getVarcharTypeDeclarationSql
(
array
$field
);
/**
* Gets the SQL snippet used to declare a CLOB column type.
*
* @param array $field
*/
abstract
public
function
getClobTypeDeclarationSql
(
array
$field
);
/**
* Gets the name of the platform.
*
* @return string
*/
abstract
public
function
getName
();
/**
* Gets the character casing of a column in an SQL result set of this platform.
*
* @param string $column The column name for which to get the correct character casing.
* @return string The column name in the character casing used in SQL result sets.
*/
public
function
getSqlResultCasing
(
$column
)
{
return
$column
;
}
/**
* Makes any fixes to a name of a schema element (table, sequence, ...) that are required
* by restrictions of the platform, like a maximum length.
*
* @param string $schemaName
* @return string
*/
public
function
fixSchemaElementName
(
$schemaElementName
)
{
return
$schemaElementName
;
}
/**
* Maximum length of any given databse identifier, like tables or column names.
*
* @return int
*/
public
function
getMaxIdentifierLength
()
{
return
63
;
}
/**
* Get the insert sql for an empty insert statement
*
* @param string $tableName
* @param string $identifierColumnName
* @return string $sql
*/
public
function
getEmptyIdentityInsertSql
(
$tableName
,
$identifierColumnName
)
{
return
'INSERT INTO '
.
$tableName
.
' ('
.
$identifierColumnName
.
') VALUES (null)'
;
}
}
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php.orig
deleted
100644 → 0
View file @
4bec3e2c
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM\Mapping\Driver
;
use
Doctrine\Common\DoctrineException
,
Doctrine\Common\Cache\ArrayCache
,
Doctrine\Common\Annotations\AnnotationReader
,
Doctrine\ORM\Mapping\ClassMetadataInfo
,
Doctrine\ORM\Mapping\MappingException
;
require
__DIR__
.
'/DoctrineAnnotations.php'
;
/**
* The AnnotationDriver reads the mapping metadata from docblock annotations.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class
AnnotationDriver
implements
Driver
{
/** The AnnotationReader. */
private
$_reader
;
private
$_classDirectory
;
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param AnnotationReader $reader The AnnotationReader to use.
*/
public
function
__construct
(
AnnotationReader
$reader
,
$classDirectory
=
null
)
{
$this
->
_reader
=
$reader
;
$this
->
_classDirectory
=
$classDirectory
;
}
public
function
setClassDirectory
(
$classDirectory
)
{
$this
->
_classDirectory
=
$classDirectory
;
}
/**
* {@inheritdoc}
*/
public
function
loadMetadataForClass
(
$className
,
ClassMetadataInfo
$metadata
)
{
$class
=
$metadata
->
getReflectionClass
();
$classAnnotations
=
$this
->
_reader
->
getClassAnnotations
(
$class
);
// Evaluate Entity annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
]))
{
$entityAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
];
$metadata
->
setCustomRepositoryClass
(
$entityAnnot
->
repositoryClass
);
}
else
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\MappedSuperclass'
]))
{
$metadata
->
isMappedSuperclass
=
true
;
}
else
{
throw
DoctrineException
::
classIsNotAValidEntityOrMappedSuperClass
(
$className
);
}
// Evaluate DoctrineTable annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Table'
]))
{
$tableAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\Table'
];
$primaryTable
=
array
(
'name'
=>
$tableAnnot
->
name
,
'schema'
=>
$tableAnnot
->
schema
);
if
(
$tableAnnot
->
indexes
!==
null
)
{
foreach
(
$tableAnnot
->
indexes
as
$indexAnnot
)
{
$primaryTable
[
'indexes'
][
$indexAnnot
->
name
]
=
array
(
'columns'
=>
$indexAnnot
->
columns
);
}
}
if
(
$tableAnnot
->
uniqueConstraints
!==
null
)
{
foreach
(
$tableAnnot
->
uniqueConstraints
as
$uniqueConstraint
)
{
$primaryTable
[
'uniqueConstraints'
][
$uniqueConstraint
->
name
]
=
array
(
'columns'
=>
$uniqueConstraint
->
columns
);
}
}
$metadata
->
setPrimaryTable
(
$primaryTable
);
}
// Evaluate InheritanceType annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\InheritanceType'
]))
{
$inheritanceTypeAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\InheritanceType'
];
$metadata
->
setInheritanceType
(
constant
(
'\Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_'
.
$inheritanceTypeAnnot
->
value
));
}
// Evaluate DiscriminatorColumn annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\DiscriminatorColumn'
]))
{
$discrColumnAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\DiscriminatorColumn'
];
$metadata
->
setDiscriminatorColumn
(
array
(
'name'
=>
$discrColumnAnnot
->
name
,
'type'
=>
$discrColumnAnnot
->
type
,
'length'
=>
$discrColumnAnnot
->
length
));
}
// Evaluate DiscriminatorMap annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\DiscriminatorMap'
]))
{
$discrMapAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\DiscriminatorMap'
];
$metadata
->
setDiscriminatorMap
(
$discrMapAnnot
->
value
);
}
// Evaluate DoctrineChangeTrackingPolicy annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\ChangeTrackingPolicy'
]))
{
$changeTrackingAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\ChangeTrackingPolicy'
];
$metadata
->
setChangeTrackingPolicy
(
$changeTrackingAnnot
->
value
);
}
// Evaluate annotations on properties/fields
foreach
(
$class
->
getProperties
()
as
$property
)
{
if
(
$metadata
->
isMappedSuperclass
&&
!
$property
->
isPrivate
()
||
$metadata
->
isInheritedField
(
$property
->
name
)
||
$metadata
->
isInheritedAssociation
(
$property
->
name
))
{
continue
;
}
$mapping
=
array
();
$mapping
[
'fieldName'
]
=
$property
->
getName
();
// Check for JoinColummn/JoinColumns annotations
$joinColumns
=
array
();
if
(
$joinColumnAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\JoinColumn'
))
{
$joinColumns
[]
=
array
(
'name'
=>
$joinColumnAnnot
->
name
,
'referencedColumnName'
=>
$joinColumnAnnot
->
referencedColumnName
,
'unique'
=>
$joinColumnAnnot
->
unique
,
'nullable'
=>
$joinColumnAnnot
->
nullable
,
'onDelete'
=>
$joinColumnAnnot
->
onDelete
,
'onUpdate'
=>
$joinColumnAnnot
->
onUpdate
);
}
else
if
(
$joinColumnsAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\JoinColumns'
))
{
foreach
(
$joinColumnsAnnot
->
value
as
$joinColumn
)
{
$joinColumns
[]
=
array
(
'name'
=>
$joinColumn
->
name
,
'referencedColumnName'
=>
$joinColumn
->
referencedColumnName
,
'unique'
=>
$joinColumn
->
unique
,
'nullable'
=>
$joinColumn
->
nullable
,
'onDelete'
=>
$joinColumn
->
onDelete
,
'onUpdate'
=>
$joinColumn
->
onUpdate
);
}
}
// Field can only be annotated with one of:
// @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
if
(
$columnAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\Column'
))
{
if
(
$columnAnnot
->
type
==
null
)
{
throw
DoctrineException
::
propertyTypeIsRequired
(
$property
->
getName
());
}
$mapping
[
'type'
]
=
$columnAnnot
->
type
;
$mapping
[
'length'
]
=
$columnAnnot
->
length
;
$mapping
[
'precision'
]
=
$columnAnnot
->
precision
;
$mapping
[
'scale'
]
=
$columnAnnot
->
scale
;
$mapping
[
'nullable'
]
=
$columnAnnot
->
nullable
;
$mapping
[
'unique'
]
=
$columnAnnot
->
unique
;
if
(
$columnAnnot
->
options
)
{
$mapping
[
'options'
]
=
$columnAnnot
->
options
;
}
if
(
isset
(
$columnAnnot
->
default
))
{
$mapping
[
'default'
]
=
$columnAnnot
->
default
;
}
if
(
isset
(
$columnAnnot
->
name
))
{
$mapping
[
'columnName'
]
=
$columnAnnot
->
name
;
}
if
(
$idAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\Id'
))
{
$mapping
[
'id'
]
=
true
;
}
if
(
$generatedValueAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\GeneratedValue'
))
{
$metadata
->
setIdGeneratorType
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
.
$generatedValueAnnot
->
strategy
));
}
if
(
$versionAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\Version'
))
{
$metadata
->
setVersionMapping
(
$mapping
);
}
$metadata
->
mapField
(
$mapping
);
// Check for SequenceGenerator/TableGenerator definition
if
(
$seqGeneratorAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\SequenceGenerator'
))
{
$metadata
->
setSequenceGeneratorDefinition
(
array
(
'sequenceName'
=>
$seqGeneratorAnnot
->
sequenceName
,
'allocationSize'
=>
$seqGeneratorAnnot
->
allocationSize
,
'initialValue'
=>
$seqGeneratorAnnot
->
initialValue
));
}
else
if
(
$tblGeneratorAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\TableGenerator'
))
{
throw
DoctrineException
::
tableIdGeneratorNotImplemented
();
}
}
else
if
(
$oneToOneAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\OneToOne'
))
{
$mapping
[
'targetEntity'
]
=
$oneToOneAnnot
->
targetEntity
;
$mapping
[
'joinColumns'
]
=
$joinColumns
;
$mapping
[
'mappedBy'
]
=
$oneToOneAnnot
->
mappedBy
;
$mapping
[
'cascade'
]
=
$oneToOneAnnot
->
cascade
;
$mapping
[
'orphanRemoval'
]
=
$oneToOneAnnot
->
orphanRemoval
;
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$oneToOneAnnot
->
fetch
);
$metadata
->
mapOneToOne
(
$mapping
);
}
else
if
(
$oneToManyAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\OneToMany'
))
{
$mapping
[
'mappedBy'
]
=
$oneToManyAnnot
->
mappedBy
;
$mapping
[
'targetEntity'
]
=
$oneToManyAnnot
->
targetEntity
;
$mapping
[
'cascade'
]
=
$oneToManyAnnot
->
cascade
;
$mapping
[
'orphanRemoval'
]
=
$oneToManyAnnot
->
orphanRemoval
;
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$oneToManyAnnot
->
fetch
);
$metadata
->
mapOneToMany
(
$mapping
);
}
else
if
(
$manyToOneAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\ManyToOne'
))
{
$mapping
[
'joinColumns'
]
=
$joinColumns
;
$mapping
[
'cascade'
]
=
$manyToOneAnnot
->
cascade
;
$mapping
[
'targetEntity'
]
=
$manyToOneAnnot
->
targetEntity
;
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$manyToOneAnnot
->
fetch
);
$metadata
->
mapManyToOne
(
$mapping
);
}
else
if
(
$manyToManyAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\ManyToMany'
))
{
$joinTable
=
array
();
if
(
$joinTableAnnot
=
$this
->
_reader
->
getPropertyAnnotation
(
$property
,
'Doctrine\ORM\Mapping\JoinTable'
))
{
$joinTable
=
array
(
'name'
=>
$joinTableAnnot
->
name
,
'schema'
=>
$joinTableAnnot
->
schema
);
foreach
(
$joinTableAnnot
->
joinColumns
as
$joinColumn
)
{
$joinTable
[
'joinColumns'
][]
=
array
(
'name'
=>
$joinColumn
->
name
,
'referencedColumnName'
=>
$joinColumn
->
referencedColumnName
,
'unique'
=>
$joinColumn
->
unique
,
'nullable'
=>
$joinColumn
->
nullable
,
'onDelete'
=>
$joinColumn
->
onDelete
,
'onUpdate'
=>
$joinColumn
->
onUpdate
);
}
foreach
(
$joinTableAnnot
->
inverseJoinColumns
as
$joinColumn
)
{
$joinTable
[
'inverseJoinColumns'
][]
=
array
(
'name'
=>
$joinColumn
->
name
,
'referencedColumnName'
=>
$joinColumn
->
referencedColumnName
,
'unique'
=>
$joinColumn
->
unique
,
'nullable'
=>
$joinColumn
->
nullable
,
'onDelete'
=>
$joinColumn
->
onDelete
,
'onUpdate'
=>
$joinColumn
->
onUpdate
);
}
}
$mapping
[
'joinTable'
]
=
$joinTable
;
$mapping
[
'targetEntity'
]
=
$manyToManyAnnot
->
targetEntity
;
$mapping
[
'mappedBy'
]
=
$manyToManyAnnot
->
mappedBy
;
$mapping
[
'cascade'
]
=
$manyToManyAnnot
->
cascade
;
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$manyToManyAnnot
->
fetch
);
$metadata
->
mapManyToMany
(
$mapping
);
}
}
// Evaluate HasLifecycleCallbacks annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\HasLifecycleCallbacks'
]))
{
foreach
(
$class
->
getMethods
()
as
$method
)
{
if
(
$method
->
isPublic
())
{
$annotations
=
$this
->
_reader
->
getMethodAnnotations
(
$method
);
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PrePersist'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
prePersist
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PostPersist'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
postPersist
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PreUpdate'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
preUpdate
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PostUpdate'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
postUpdate
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PreRemove'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
preRemove
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PostRemove'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
postRemove
);
}
if
(
isset
(
$annotations
[
'Doctrine\ORM\Mapping\PostLoad'
]))
{
$metadata
->
addLifecycleCallback
(
$method
->
getName
(),
\Doctrine\ORM\Events
::
postLoad
);
}
}
}
}
}
/**
* Whether the class with the specified name should have its metadata loaded.
* This is only the case if it is annotated with either @Entity or
* @MappedSuperclass in the class doc block.
*
* @param string $className
* @return boolean
*/
public
function
isTransient
(
$className
)
{
$classAnnotations
=
$this
->
_reader
->
getClassAnnotations
(
new
\ReflectionClass
(
$className
));
return
!
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
])
&&
!
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\MappedSuperclass'
]);
}
/**
* {@inheritDoc}
*/
public
function
getAllClassNames
()
{
if
(
$this
->
_classDirectory
)
{
$iter
=
new
\RecursiveIteratorIterator
(
new
\RecursiveDirectoryIterator
(
$this
->
_classDirectory
),
\RecursiveIteratorIterator
::
LEAVES_ONLY
);
$declared
=
get_declared_classes
();
foreach
(
$iter
as
$item
)
{
$info
=
pathinfo
(
$item
->
getPathName
());
if
(
!
isset
(
$info
[
'extension'
])
||
$info
[
'extension'
]
!=
'php'
)
{
continue
;
}
require_once
$item
->
getPathName
();
}
$declared
=
array_diff
(
get_declared_classes
(),
$declared
);
$classes
=
array
();
foreach
(
$declared
as
$className
)
{
if
(
!
$this
->
isTransient
(
$className
))
{
$classes
[]
=
$className
;
}
}
return
$classes
;
}
else
{
return
array
();
}
}
}
\ No newline at end of file
lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php.orig
deleted
100644 → 0
View file @
4bec3e2c
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM\Mapping\Driver
;
use
Doctrine\ORM\Mapping\ClassMetadataInfo
,
Doctrine\ORM\Mapping\MappingException
;
/**
* XmlDriver is a metadata driver that enables mapping through XML files.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class
XmlDriver
extends
AbstractFileDriver
{
protected
$_fileExtension
=
'.dcm.xml'
;
/**
* Loads the metadata for the specified class into the provided container.
*
* @param string $className
* @param ClassMetadata $metadata
*/
public
function
loadMetadataForClass
(
$className
,
ClassMetadataInfo
$metadata
)
{
$xmlRoot
=
$this
->
getElement
(
$className
);
if
(
$xmlRoot
->
getName
()
==
'entity'
)
{
$metadata
->
setCustomRepositoryClass
(
isset
(
$xmlRoot
[
'repository-class'
])
?
(
string
)
$xmlRoot
[
'repository-class'
]
:
null
);
}
else
if
(
$xmlRoot
->
getName
()
==
'mapped-superclass'
)
{
$metadata
->
isMappedSuperclass
=
true
;
}
else
{
throw
DoctrineException
::
classIsNotAValidEntityOrMapperSuperClass
(
$className
);
}
// Evaluate <entity...> attributes
if
(
isset
(
$xmlRoot
[
'table'
]))
{
$metadata
->
primaryTable
[
'name'
]
=
(
string
)
$xmlRoot
[
'table'
];
}
if
(
isset
(
$xmlRoot
[
'schema'
]))
{
$metadata
->
primaryTable
[
'schema'
]
=
(
string
)
$xmlRoot
[
'schema'
];
}
if
(
isset
(
$xmlRoot
[
'inheritance-type'
]))
{
$metadata
->
setInheritanceType
((
string
)
$xmlRoot
[
'inheritance-type'
]);
}
// Evaluate <discriminator-column...>
if
(
isset
(
$xmlRoot
->
{
'discriminator-column'
}))
{
$discrColumn
=
$xmlRoot
->
{
'discriminator-column'
};
$metadata
->
setDiscriminatorColumn
(
array
(
'name'
=>
(
string
)
$discrColumn
[
'name'
],
'type'
=>
(
string
)
$discrColumn
[
'type'
],
'length'
=>
(
string
)
$discrColumn
[
'length'
]
));
}
// Evaluate <discriminator-map...>
if
(
isset
(
$xmlRoot
->
{
'discriminator-map'
}))
{
$metadata
->
setDiscriminatorMap
((
array
)
$xmlRoot
->
{
'discriminator-map'
});
}
// Evaluate <change-tracking-policy...>
if
(
isset
(
$xmlRoot
->
{
'change-tracking-policy'
}))
{
$metadata
->
setChangeTrackingPolicy
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
.
strtoupper
((
string
)
$xmlRoot
->
{
'change-tracking-policy'
})));
}
// Evaluate <indexes...>
if
(
isset
(
$xmlRoot
->
indexes
))
{
foreach
(
$xmlRoot
->
indexes
->
index
as
$index
)
{
if
(
is_string
(
$index
[
'columns'
]))
{
$columns
=
explode
(
','
,
$index
[
'columns'
]);
}
else
{
$columns
=
$index
[
'columns'
];
}
$metadata
->
primaryTable
[
'indexes'
][
$index
[
'name'
]]
=
array
(
'columns'
=>
$columns
);
}
}
// Evaluate <unique-constraints..>
if
(
isset
(
$xmlRoot
->
{
'unique-constraints'
}))
{
foreach
(
$xmlRoot
->
{
'unique-constraints'
}
->
{
'unique-constraint'
}
as
$unique
)
{
if
(
is_string
(
$unique
[
'columns'
]))
{
$columns
=
explode
(
','
,
$unique
[
'columns'
]);
}
else
{
$columns
=
$unique
[
'columns'
];
}
$metadata
->
primaryTable
[
'uniqueConstraints'
][
$unique
[
'name'
]]
=
array
(
'columns'
=>
$columns
);
}
}
// Evaluate <field ...> mappings
if
(
isset
(
$xmlRoot
->
field
))
{
foreach
(
$xmlRoot
->
field
as
$fieldMapping
)
{
$mapping
=
array
(
'fieldName'
=>
(
string
)
$fieldMapping
[
'name'
],
'type'
=>
(
string
)
$fieldMapping
[
'type'
]
);
if
(
isset
(
$fieldMapping
[
'column'
]))
{
$mapping
[
'columnName'
]
=
(
string
)
$fieldMapping
[
'column'
];
}
if
(
isset
(
$fieldMapping
[
'length'
]))
{
$mapping
[
'length'
]
=
(
int
)
$fieldMapping
[
'length'
];
}
if
(
isset
(
$fieldMapping
[
'precision'
]))
{
$mapping
[
'precision'
]
=
(
int
)
$fieldMapping
[
'precision'
];
}
if
(
isset
(
$fieldMapping
[
'scale'
]))
{
$mapping
[
'scale'
]
=
(
int
)
$fieldMapping
[
'scale'
];
}
if
(
isset
(
$fieldMapping
[
'unique'
]))
{
$mapping
[
'unique'
]
=
(
bool
)
$fieldMapping
[
'unique'
];
}
if
(
isset
(
$fieldMapping
[
'options'
]))
{
$mapping
[
'options'
]
=
(
array
)
$fieldMapping
[
'options'
];
}
if
(
isset
(
$fieldMapping
[
'version'
])
&&
$fieldMapping
[
'version'
])
{
$metadata
->
setVersionMapping
(
$mapping
);
}
$metadata
->
mapField
(
$mapping
);
}
}
// Evaluate <id ...> mappings
foreach
(
$xmlRoot
->
id
as
$idElement
)
{
$mapping
=
array
(
'id'
=>
true
,
'fieldName'
=>
(
string
)
$idElement
[
'name'
],
'type'
=>
(
string
)
$idElement
[
'type'
]
);
if
(
isset
(
$idElement
[
'column'
]))
{
$mapping
[
'columnName'
]
=
(
string
)
$idElement
[
'column'
];
}
$metadata
->
mapField
(
$mapping
);
if
(
isset
(
$idElement
->
generator
))
{
$metadata
->
setIdGeneratorType
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
.
strtoupper
((
string
)
$idElement
->
generator
[
'strategy'
])));
}
// Check for SequenceGenerator/TableGenerator definition
if
(
isset
(
$idElement
->
{
'sequence-generator'
}))
{
$seqGenerator
=
$idElement
->
{
'sequence-generator'
};
$metadata
->
setSequenceGeneratorDefinition
(
array
(
'sequenceName'
=>
$seqGenerator
->
{
'sequence-name'
},
'allocationSize'
=>
$seqGenerator
->
{
'allocation-size'
},
'initialValue'
=>
$seqGeneratorAnnot
->
{
'initial-value'
}
));
}
else
if
(
isset
(
$idElement
->
{
'table-generator'
}))
{
throw
DoctrineException
::
tableIdGeneratorNotImplemented
();
}
}
// Evaluate <one-to-one ...> mappings
if
(
isset
(
$xmlRoot
->
{
'one-to-one'
}))
{
foreach
(
$xmlRoot
->
{
'one-to-one'
}
as
$oneToOneElement
)
{
$mapping
=
array
(
'fieldName'
=>
(
string
)
$oneToOneElement
[
'field'
],
'targetEntity'
=>
(
string
)
$oneToOneElement
[
'target-entity'
]
);
if
(
isset
(
$oneToOneElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
(
string
)
$oneToOneElement
[
'fetch'
]);
}
if
(
isset
(
$oneToOneElement
[
'mapped-by'
]))
{
$mapping
[
'mappedBy'
]
=
(
string
)
$oneToOneElement
[
'mapped-by'
];
}
else
{
$joinColumns
=
array
();
if
(
isset
(
$oneToOneElement
->
{
'join-column'
}))
{
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$oneToOneElement
->
{
'join-column'
});
}
else
if
(
isset
(
$oneToOneElement
->
{
'join-columns'
}))
{
foreach
(
$oneToOneElement
->
{
'join-columns'
}
->
{
'join-column'
}
as
$joinColumnElement
)
{
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
$mapping
[
'joinColumns'
]
=
$joinColumns
;
}
if
(
isset
(
$oneToOneElement
->
cascade
))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$oneToOneElement
->
cascade
);
}
if
(
isset
(
$oneToOneElement
->
{
'orphan-removal'
}))
{
$mapping
[
'orphanRemoval'
]
=
(
bool
)
$oneToOneElement
->
{
'orphan-removal'
};
}
$metadata
->
mapOneToOne
(
$mapping
);
}
}
// Evaluate <one-to-many ...> mappings
if
(
isset
(
$xmlRoot
->
{
'one-to-many'
}))
{
foreach
(
$xmlRoot
->
{
'one-to-many'
}
as
$oneToManyElement
)
{
$mapping
=
array
(
'fieldName'
=>
(
string
)
$oneToManyElement
[
'field'
],
'targetEntity'
=>
(
string
)
$oneToManyElement
[
'target-entity'
],
'mappedBy'
=>
(
string
)
$oneToManyElement
[
'mapped-by'
]
);
if
(
isset
(
$oneToManyElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
(
string
)
$oneToManyElement
[
'fetch'
]);
}
if
(
isset
(
$oneToManyElement
->
cascade
))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$oneToManyElement
->
cascade
);
}
if
(
isset
(
$oneToManyElement
->
{
'orphan-removal'
}))
{
$mapping
[
'orphanRemoval'
]
=
(
bool
)
$oneToManyElement
->
{
'orphan-removal'
};
}
$metadata
->
mapOneToMany
(
$mapping
);
}
}
// Evaluate <many-to-one ...> mappings
if
(
isset
(
$xmlRoot
->
{
'many-to-one'
}))
{
foreach
(
$xmlRoot
->
{
'many-to-one'
}
as
$manyToOneElement
)
{
$mapping
=
array
(
'fieldName'
=>
(
string
)
$manyToOneElement
[
'field'
],
'targetEntity'
=>
(
string
)
$manyToOneElement
[
'target-entity'
]
);
if
(
isset
(
$manyToOneElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
(
string
)
$manyToOneElement
[
'fetch'
]);
}
$joinColumns
=
array
();
if
(
isset
(
$manyToOneElement
->
{
'join-column'
}))
{
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$manyToOneElement
->
{
'join-column'
});
}
else
if
(
isset
(
$manyToOneElement
->
{
'join-columns'
}))
{
foreach
(
$manyToOneElement
->
{
'join-columns'
}
->
{
'join-column'
}
as
$joinColumnElement
)
{
if
(
!
isset
(
$joinColumnElement
[
'name'
]))
{
$joinColumnElement
[
'name'
]
=
$name
;
}
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
$mapping
[
'joinColumns'
]
=
$joinColumns
;
if
(
isset
(
$manyToOneElement
->
cascade
))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$manyToOneElement
->
cascade
);
}
if
(
isset
(
$manyToOneElement
->
{
'orphan-removal'
}))
{
$mapping
[
'orphanRemoval'
]
=
(
bool
)
$manyToOneElement
->
{
'orphan-removal'
};
}
$metadata
->
mapManyToOne
(
$mapping
);
}
}
// Evaluate <many-to-many ...> mappings
if
(
isset
(
$xmlRoot
->
{
'many-to-many'
}))
{
foreach
(
$xmlRoot
->
{
'many-to-many'
}
as
$manyToManyElement
)
{
$mapping
=
array
(
'fieldName'
=>
(
string
)
$manyToManyElement
[
'field'
],
'targetEntity'
=>
(
string
)
$manyToManyElement
[
'target-entity'
]
);
if
(
isset
(
$manyToManyElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
(
string
)
$manyToManyElement
[
'fetch'
]);
}
if
(
isset
(
$manyToManyElement
[
'mapped-by'
]))
{
$mapping
[
'mappedBy'
]
=
(
string
)
$manyToManyElement
[
'mapped-by'
];
}
else
if
(
isset
(
$manyToManyElement
->
{
'join-table'
}))
{
$joinTableElement
=
$manyToManyElement
->
{
'join-table'
};
$joinTable
=
array
(
'name'
=>
(
string
)
$joinTableElement
[
'name'
]
);
if
(
isset
(
$joinTableElement
[
'schema'
]))
{
$joinTable
[
'schema'
]
=
(
string
)
$joinTableElement
[
'schema'
];
}
foreach
(
$joinTableElement
->
{
'join-columns'
}
->
{
'join-column'
}
as
$joinColumnElement
)
{
$joinTable
[
'joinColumns'
][]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
foreach
(
$joinTableElement
->
{
'inverse-join-columns'
}
->
{
'join-column'
}
as
$joinColumnElement
)
{
$joinTable
[
'inverseJoinColumns'
][]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
$mapping
[
'joinTable'
]
=
$joinTable
;
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
if
(
isset
(
$manyToManyElement
->
cascade
))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$manyToManyElement
->
cascade
);
}
if
(
isset
(
$manyToManyElement
->
{
'orphan-removal'
}))
{
$mapping
[
'orphanRemoval'
]
=
(
bool
)
$manyToManyElement
->
{
'orphan-removal'
};
}
$metadata
->
mapManyToMany
(
$mapping
);
}
}
// Evaluate <lifecycle-callbacks...>
if
(
isset
(
$xmlRoot
->
{
'lifecycle-callbacks'
}))
{
foreach
(
$xmlRoot
->
{
'lifecycle-callbacks'
}
->
{
'lifecycle-callback'
}
as
$lifecycleCallback
)
{
$metadata
->
addLifecycleCallback
((
string
)
$lifecycleCallback
[
'method'
],
constant
(
'\Doctrine\ORM\Events::'
.
(
string
)
$lifecycleCallback
[
'type'
]));
}
}
}
/**
* Loads a mapping file with the given name and returns a map
* from class/entity names to their corresponding SimpleXMLElement nodes.
*
* @param string $file The mapping file to load.
* @return array
*/
protected
function
_loadMappingFile
(
$file
)
{
$result
=
array
();
$xmlElement
=
simplexml_load_file
(
$file
);
if
(
isset
(
$xmlElement
->
entity
))
{
foreach
(
$xmlElement
->
entity
as
$entityElement
)
{
$entityName
=
(
string
)
$entityElement
[
'name'
];
$result
[
$entityName
]
=
$entityElement
;
}
}
else
if
(
isset
(
$xmlElement
->
{
'mapped-superclass'
}))
{
foreach
(
$xmlElement
->
{
'mapped-superclass'
}
as
$mapperSuperClass
)
{
$className
=
(
string
)
$mappedSuperClass
[
'name'
];
$result
[
$className
]
=
$mappedSuperClass
;
}
}
return
$result
;
}
/**
* Constructs a joinColumn mapping array based on the information
* found in the given SimpleXMLElement.
*
* @param $joinColumnElement The XML element.
* @return array The mapping array.
*/
private
function
_getJoinColumnMapping
(
\SimpleXMLElement
$joinColumnElement
)
{
$joinColumn
=
array
(
'name'
=>
(
string
)
$joinColumnElement
[
'name'
],
'referencedColumnName'
=>
(
string
)
$joinColumnElement
[
'referenced-column-name'
]
);
if
(
isset
(
$joinColumnElement
[
'unique'
]))
{
$joinColumn
[
'unique'
]
=
(
bool
)
$joinColumnElement
[
'unique'
];
}
if
(
isset
(
$joinColumnElement
[
'nullable'
]))
{
$joinColumn
[
'nullable'
]
=
(
bool
)
$joinColumnElement
[
'nullable'
];
}
if
(
isset
(
$joinColumnElement
[
'onDelete'
]))
{
$joinColumn
[
'onDelete'
]
=
(
string
)
$joinColumnElement
[
'on-delete'
];
}
if
(
isset
(
$joinColumnElement
[
'onUpdate'
]))
{
$joinColumn
[
'onUpdate'
]
=
(
string
)
$joinColumnElement
[
'on-update'
];
}
return
$joinColumn
;
}
/**
* Gathers a list of cascade options found in the given cascade element.
*
* @param $cascadeElement The cascade element.
* @return array The list of cascade options.
*/
private
function
_getCascadeMappings
(
$cascadeElement
)
{
$cascades
=
array
();
if
(
isset
(
$cascadeElement
->
{
'cascade-persist'
}))
{
$cascades
[]
=
'persist'
;
}
if
(
isset
(
$cascadeElement
->
{
'cascade-remove'
}))
{
$cascades
[]
=
'remove'
;
}
if
(
isset
(
$cascadeElement
->
{
'cascade-merge'
}))
{
$cascades
[]
=
'merge'
;
}
if
(
isset
(
$cascadeElement
->
{
'cascade-refresh'
}))
{
$cascades
[]
=
'refresh'
;
}
return
$cascades
;
}
}
\ No newline at end of file
lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php.orig
deleted
100644 → 0
View file @
4bec3e2c
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM\Mapping\Driver
;
use
Doctrine\ORM\Mapping\ClassMetadataInfo
,
Doctrine\Common\DoctrineException
,
Doctrine\ORM\Mapping\MappingException
;
if
(
!
class_exists
(
'sfYaml'
,
false
))
{
require_once
__DIR__
.
'/../../../../vendor/sfYaml/sfYaml.class.php'
;
require_once
__DIR__
.
'/../../../../vendor/sfYaml/sfYamlDumper.class.php'
;
require_once
__DIR__
.
'/../../../../vendor/sfYaml/sfYamlInline.class.php'
;
require_once
__DIR__
.
'/../../../../vendor/sfYaml/sfYamlParser.class.php'
;
}
/**
* The YamlDriver reads the mapping metadata from yaml schema files.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class
YamlDriver
extends
AbstractFileDriver
{
protected
$_fileExtension
=
'.dcm.yml'
;
public
function
loadMetadataForClass
(
$className
,
ClassMetadataInfo
$metadata
)
{
$element
=
$this
->
getElement
(
$className
);
if
(
$element
[
'type'
]
==
'entity'
)
{
$metadata
->
setCustomRepositoryClass
(
isset
(
$element
[
'repositoryClass'
])
?
$element
[
'repositoryClass'
]
:
null
);
}
else
if
(
$element
[
'type'
]
==
'mappedSuperclass'
)
{
$metadata
->
isMappedSuperclass
=
true
;
}
else
{
throw
DoctrineException
::
classIsNotAValidEntityOrMapperSuperClass
(
$className
);
}
// Evaluate root level properties
if
(
isset
(
$element
[
'table'
]))
{
$metadata
->
primaryTable
[
'name'
]
=
$element
[
'table'
];
}
if
(
isset
(
$element
[
'schema'
]))
{
$metadata
->
primaryTable
[
'schema'
]
=
$element
[
'schema'
];
}
if
(
isset
(
$element
[
'inheritanceType'
]))
{
$metadata
->
setInheritanceType
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_'
.
strtoupper
(
$element
[
'inheritanceType'
])));
}
// Evaluate discriminatorColumn
if
(
isset
(
$element
[
'discriminatorColumn'
]))
{
$discrColumn
=
$element
[
'discriminatorColumn'
];
$metadata
->
setDiscriminatorColumn
(
array
(
'name'
=>
$discrColumn
[
'name'
],
'type'
=>
$discrColumn
[
'type'
],
'length'
=>
$discrColumn
[
'length'
]
));
}
// Evaluate discriminatorMap
if
(
isset
(
$element
[
'discriminatorMap'
]))
{
$metadata
->
setDiscriminatorMap
(
$element
[
'discriminatorMap'
]);
}
// Evaluate changeTrackingPolicy
if
(
isset
(
$element
[
'changeTrackingPolicy'
]))
{
$metadata
->
setChangeTrackingPolicy
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
.
strtoupper
(
$element
[
'changeTrackingPolicy'
])));
}
// Evaluate indexes
if
(
isset
(
$element
[
'indexes'
]))
{
foreach
(
$element
[
'indexes'
]
as
$name
=>
$index
)
{
if
(
!
isset
(
$index
[
'name'
]))
{
$index
[
'name'
]
=
$name
;
}
if
(
is_string
(
$index
[
'columns'
]))
{
$columns
=
explode
(
','
,
$index
[
'columns'
]);
}
else
{
$columns
=
$index
[
'columns'
];
}
$metadata
->
primaryTable
[
'indexes'
][
$index
[
'name'
]]
=
array
(
'columns'
=>
$columns
);
}
}
// Evaluate uniqueConstraints
if
(
isset
(
$element
[
'uniqueConstraints'
]))
{
foreach
(
$element
[
'uniqueConstraints'
]
as
$name
=>
$unique
)
{
if
(
!
isset
(
$unique
[
'name'
]))
{
$unique
[
'name'
]
=
$name
;
}
if
(
is_string
(
$unique
[
'columns'
]))
{
$columns
=
explode
(
','
,
$unique
[
'columns'
]);
}
else
{
$columns
=
$unique
[
'columns'
];
}
$metadata
->
primaryTable
[
'uniqueConstraints'
][
$unique
[
'name'
]]
=
array
(
'columns'
=>
$columns
);
}
}
if
(
isset
(
$element
[
'id'
]))
{
// Evaluate identifier settings
foreach
(
$element
[
'id'
]
as
$name
=>
$idElement
)
{
$mapping
=
array
(
'id'
=>
true
,
'fieldName'
=>
$name
,
'type'
=>
$idElement
[
'type'
]
);
if
(
isset
(
$idElement
[
'column'
]))
{
$mapping
[
'columnName'
]
=
$idElement
[
'column'
];
}
$metadata
->
mapField
(
$mapping
);
if
(
isset
(
$idElement
[
'generator'
]))
{
$metadata
->
setIdGeneratorType
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
.
strtoupper
(
$idElement
[
'generator'
][
'strategy'
])));
}
}
}
// Evaluate fields
if
(
isset
(
$element
[
'fields'
]))
{
foreach
(
$element
[
'fields'
]
as
$name
=>
$fieldMapping
)
{
$e
=
explode
(
'('
,
$fieldMapping
[
'type'
]);
$fieldMapping
[
'type'
]
=
$e
[
0
];
if
(
isset
(
$e
[
1
]))
{
$fieldMapping
[
'length'
]
=
substr
(
$e
[
1
],
0
,
strlen
(
$e
[
1
])
-
1
);
}
$mapping
=
array
(
'fieldName'
=>
$name
,
'type'
=>
$fieldMapping
[
'type'
]
);
if
(
isset
(
$fieldMapping
[
'id'
]))
{
$mapping
[
'id'
]
=
true
;
if
(
isset
(
$fieldMapping
[
'generator'
][
'strategy'
]))
{
$metadata
->
setIdGeneratorType
(
constant
(
'Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
.
strtoupper
(
$fieldMapping
[
'generator'
][
'strategy'
])));
}
}
// Check for SequenceGenerator/TableGenerator definition
if
(
isset
(
$fieldMapping
[
'sequenceGenerator'
]))
{
$metadata
->
setSequenceGeneratorDefinition
(
$fieldMapping
[
'sequenceGenerator'
]);
}
else
if
(
isset
(
$fieldMapping
[
'tableGenerator'
]))
{
throw
DoctrineException
::
tableIdGeneratorNotImplemented
();
}
if
(
isset
(
$fieldMapping
[
'column'
]))
{
$mapping
[
'columnName'
]
=
$fieldMapping
[
'column'
];
}
if
(
isset
(
$fieldMapping
[
'length'
]))
{
$mapping
[
'length'
]
=
$fieldMapping
[
'length'
];
}
if
(
isset
(
$fieldMapping
[
'precision'
]))
{
$mapping
[
'precision'
]
=
$fieldMapping
[
'precision'
];
}
if
(
isset
(
$fieldMapping
[
'scale'
]))
{
$mapping
[
'scale'
]
=
$fieldMapping
[
'scale'
];
}
if
(
isset
(
$fieldMapping
[
'unique'
]))
{
$mapping
[
'unique'
]
=
(
bool
)
$fieldMapping
[
'unique'
];
}
if
(
isset
(
$fieldMapping
[
'options'
]))
{
$mapping
[
'options'
]
=
$fieldMapping
[
'options'
];
}
if
(
isset
(
$fieldMapping
[
'nullable'
]))
{
$mapping
[
'nullable'
]
=
$fieldMapping
[
'nullable'
];
}
if
(
isset
(
$fieldMapping
[
'version'
])
&&
$fieldMapping
[
'version'
])
{
$metadata
->
setVersionMapping
(
$mapping
);
}
$metadata
->
mapField
(
$mapping
);
}
}
// Evaluate oneToOne relationships
if
(
isset
(
$element
[
'oneToOne'
]))
{
foreach
(
$element
[
'oneToOne'
]
as
$name
=>
$oneToOneElement
)
{
$mapping
=
array
(
'fieldName'
=>
$name
,
'targetEntity'
=>
$oneToOneElement
[
'targetEntity'
]
);
if
(
isset
(
$oneToOneElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$oneToOneElement
[
'fetch'
]);
}
if
(
isset
(
$oneToOneElement
[
'mappedBy'
]))
{
$mapping
[
'mappedBy'
]
=
$oneToOneElement
[
'mappedBy'
];
}
else
{
$joinColumns
=
array
();
if
(
isset
(
$oneToOneElement
[
'joinColumn'
]))
{
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$oneToOneElement
[
'joinColumn'
]);
}
else
if
(
isset
(
$oneToOneElement
[
'joinColumns'
]))
{
foreach
(
$oneToOneElement
[
'joinColumns'
]
as
$name
=>
$joinColumnElement
)
{
if
(
!
isset
(
$joinColumnElement
[
'name'
]))
{
$joinColumnElement
[
'name'
]
=
$name
;
}
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
$mapping
[
'joinColumns'
]
=
$joinColumns
;
}
if
(
isset
(
$oneToOneElement
[
'cascade'
]))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$oneToOneElement
[
'cascade'
]);
}
$metadata
->
mapOneToOne
(
$mapping
);
}
}
// Evaluate oneToMany relationships
if
(
isset
(
$element
[
'oneToMany'
]))
{
foreach
(
$element
[
'oneToMany'
]
as
$name
=>
$oneToManyElement
)
{
$mapping
=
array
(
'fieldName'
=>
$name
,
'targetEntity'
=>
$oneToManyElement
[
'targetEntity'
],
'mappedBy'
=>
$oneToManyElement
[
'mappedBy'
]
);
if
(
isset
(
$oneToManyElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$oneToManyElement
[
'fetch'
]);
}
if
(
isset
(
$oneToManyElement
[
'cascade'
]))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$oneToManyElement
[
'cascade'
]);
}
$metadata
->
mapOneToMany
(
$mapping
);
}
}
// Evaluate manyToOne relationships
if
(
isset
(
$element
[
'manyToOne'
]))
{
foreach
(
$element
[
'manyToOne'
]
as
$name
=>
$manyToOneElement
)
{
$mapping
=
array
(
'fieldName'
=>
$name
,
'targetEntity'
=>
$manyToOneElement
[
'targetEntity'
]
);
if
(
isset
(
$manyToOneElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$manyToOneElement
[
'fetch'
]);
}
$joinColumns
=
array
();
if
(
isset
(
$manyToOneElement
[
'joinColumn'
]))
{
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$manyToOneElement
[
'joinColumn'
]);
}
else
if
(
isset
(
$manyToOneElement
[
'joinColumns'
]))
{
foreach
(
$manyToOneElement
[
'joinColumns'
]
as
$name
=>
$joinColumnElement
)
{
if
(
!
isset
(
$joinColumnElement
[
'name'
]))
{
$joinColumnElement
[
'name'
]
=
$name
;
}
$joinColumns
[]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
$mapping
[
'joinColumns'
]
=
$joinColumns
;
if
(
isset
(
$manyToOneElement
[
'cascade'
]))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$manyToOneElement
[
'cascade'
]);
}
$metadata
->
mapManyToOne
(
$mapping
);
}
}
// Evaluate manyToMany relationships
if
(
isset
(
$element
[
'manyToMany'
]))
{
foreach
(
$element
[
'manyToMany'
]
as
$name
=>
$manyToManyElement
)
{
$mapping
=
array
(
'fieldName'
=>
$name
,
'targetEntity'
=>
$manyToManyElement
[
'targetEntity'
]
);
if
(
isset
(
$manyToManyElement
[
'fetch'
]))
{
$mapping
[
'fetch'
]
=
constant
(
'Doctrine\ORM\Mapping\AssociationMapping::FETCH_'
.
$manyToManyElement
[
'fetch'
]);
}
if
(
isset
(
$manyToManyElement
[
'mappedBy'
]))
{
$mapping
[
'mappedBy'
]
=
$manyToManyElement
[
'mappedBy'
];
}
else
if
(
isset
(
$manyToManyElement
[
'joinTable'
]))
{
$joinTableElement
=
$manyToManyElement
[
'joinTable'
];
$joinTable
=
array
(
'name'
=>
$joinTableElement
[
'name'
]
);
if
(
isset
(
$joinTableElement
[
'schema'
]))
{
$joinTable
[
'schema'
]
=
$joinTableElement
[
'schema'
];
}
foreach
(
$joinTableElement
[
'joinColumns'
]
as
$name
=>
$joinColumnElement
)
{
if
(
!
isset
(
$joinColumnElement
[
'name'
]))
{
$joinColumnElement
[
'name'
]
=
$name
;
}
$joinTable
[
'joinColumns'
][]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
foreach
(
$joinTableElement
[
'inverseJoinColumns'
]
as
$name
=>
$joinColumnElement
)
{
if
(
!
isset
(
$joinColumnElement
[
'name'
]))
{
$joinColumnElement
[
'name'
]
=
$name
;
}
$joinTable
[
'inverseJoinColumns'
][]
=
$this
->
_getJoinColumnMapping
(
$joinColumnElement
);
}
$mapping
[
'joinTable'
]
=
$joinTable
;
}
else
{
throw
MappingException
::
invalidMapping
(
$mapping
[
'fieldName'
]);
}
if
(
isset
(
$manyToManyElement
[
'cascade'
]))
{
$mapping
[
'cascade'
]
=
$this
->
_getCascadeMappings
(
$manyToManyElement
[
'cascade'
]);
}
$metadata
->
mapManyToMany
(
$mapping
);
}
}
// Evaluate lifeCycleCallbacks
if
(
isset
(
$element
[
'lifecycleCallbacks'
]))
{
foreach
(
$element
[
'lifecycleCallbacks'
]
as
$method
=>
$type
)
{
$metadata
->
addLifecycleCallback
(
$method
,
constant
(
'\Doctrine\ORM\Events::'
.
$type
));
}
}
}
/**
* Constructs a joinColumn mapping array based on the information
* found in the given join column element.
*
* @param $joinColumnElement The array join column element
* @return array The mapping array.
*/
private
function
_getJoinColumnMapping
(
$joinColumnElement
)
{
$joinColumn
=
array
(
'name'
=>
$joinColumnElement
[
'name'
],
'referencedColumnName'
=>
$joinColumnElement
[
'referencedColumnName'
]
);
if
(
isset
(
$joinColumnElement
[
'fieldName'
]))
{
$joinColumn
[
'fieldName'
]
=
(
string
)
$joinColumnElement
[
'fieldName'
];
}
if
(
isset
(
$joinColumnElement
[
'unique'
]))
{
$joinColumn
[
'unique'
]
=
(
bool
)
$joinColumnElement
[
'unique'
];
}
if
(
isset
(
$joinColumnElement
[
'nullable'
]))
{
$joinColumn
[
'nullable'
]
=
(
bool
)
$joinColumnElement
[
'nullable'
];
}
if
(
isset
(
$joinColumnElement
[
'onDelete'
]))
{
$joinColumn
[
'onDelete'
]
=
$joinColumnElement
[
'onDelete'
];
}
if
(
isset
(
$joinColumnElement
[
'onUpdate'
]))
{
$joinColumn
[
'onUpdate'
]
=
$joinColumnElement
[
'onUpdate'
];
}
return
$joinColumn
;
}
/**
* Gathers a list of cascade options found in the given cascade element.
*
* @param $cascadeElement The cascade element.
* @return array The list of cascade options.
*/
private
function
_getCascadeMappings
(
$cascadeElement
)
{
$cascades
=
array
();
if
(
isset
(
$cascadeElement
[
'cascadePersist'
]))
{
$cascades
[]
=
'persist'
;
}
if
(
isset
(
$cascadeElement
[
'cascadeRemove'
]))
{
$cascades
[]
=
'remove'
;
}
if
(
isset
(
$cascadeElement
[
'cascadeMerge'
]))
{
$cascades
[]
=
'merge'
;
}
if
(
isset
(
$cascadeElement
[
'cascadeRefresh'
]))
{
$cascades
[]
=
'refresh'
;
}
return
$cascades
;
}
/**
* Loads a mapping file with the given name and returns a map
* from class/entity names to their corresponding elements.
*
* @param string $file The mapping file to load.
* @return array
*/
protected
function
_loadMappingFile
(
$file
)
{
return
\sfYaml
::
load
(
$file
);
}
}
\ No newline at end of file
lib/Doctrine/ORM/Tools/SchemaTool.php.orig
deleted
100644 → 0
View file @
4bec3e2c
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\ORM\Tools
;
use
Doctrine\DBAL\Types\Type
,
Doctrine\ORM\EntityManager
,
Doctrine\ORM\Internal\CommitOrderCalculator
;
/**
* The SchemaTool is a tool to create/drop/update database schemas based on
* <tt>ClassMetadata</tt> class descriptors.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class
SchemaTool
{
/**
* @var string
*/
const
DROP_METADATA
=
"metadata"
;
/**
* @var string
*/
const
DROP_DATABASE
=
"database"
;
/**
* @var \Doctrine\ORM\EntityManager
*/
private
$_em
;
/**
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private
$_platform
;
/**
* Initializes a new SchemaTool instance that uses the connection of the
* provided EntityManager.
*
* @param Doctrine\ORM\EntityManager $em
*/
public
function
__construct
(
EntityManager
$em
)
{
$this
->
_em
=
$em
;
$this
->
_platform
=
$em
->
getConnection
()
->
getDatabasePlatform
();
}
/**
* Creates the database schema for the given array of ClassMetadata instances.
*
* @param array $classes
*/
public
function
createSchema
(
array
$classes
)
{
$createSchemaSql
=
$this
->
getCreateSchemaSql
(
$classes
);
$conn
=
$this
->
_em
->
getConnection
();
foreach
(
$createSchemaSql
as
$sql
)
{
$conn
->
execute
(
$sql
);
}
}
/**
* Gets the list of DDL statements that are required to create the database schema for
* the given list of ClassMetadata instances.
*
* @param array $classes
* @return array $sql The SQL statements needed to create the schema for the classes.
*/
public
function
getCreateSchemaSql
(
array
$classes
)
{
$schema
=
$this
->
getSchemaFromMetadata
(
$classes
);
return
$schema
->
toSql
(
$this
->
_platform
);
}
/**
* From a given set of metadata classes this method creates a Schema instance.
*
* @param array $classes
* @return Schema
*/
public
function
getSchemaFromMetadata
(
array
$classes
)
{
$processedClasses
=
array
();
// Reminder for processed classes, used for hierarchies
$sm
=
$this
->
_em
->
getConnection
()
->
getSchemaManager
();
$schema
=
new
\Doctrine\DBAL\Schema\Schema
(
array
(),
array
(),
$sm
->
createSchemaConfig
());
foreach
(
$classes
as
$class
)
{
if
(
isset
(
$processedClasses
[
$class
->
name
])
||
$class
->
isMappedSuperclass
)
{
continue
;
}
$table
=
$schema
->
createTable
(
$class
->
getQuotedTableName
(
$this
->
_platform
));
if
(
$class
->
isIdGeneratorIdentity
())
{
$table
->
setIdGeneratorType
(
\Doctrine\DBAL\Schema\Table
::
ID_IDENTITY
);
}
else
if
(
$class
->
isIdGeneratorSequence
())
{
$table
->
setIdGeneratorType
(
\Doctrine\DBAL\Schema\Table
::
ID_SEQUENCE
);
}
$columns
=
array
();
// table columns
if
(
$class
->
isInheritanceTypeSingleTable
())
{
$columns
=
$this
->
_gatherColumns
(
$class
,
$table
);
$this
->
_gatherRelationsSql
(
$class
,
$table
,
$schema
);
// Add the discriminator column
$discrColumnDef
=
$this
->
_getDiscriminatorColumnDefinition
(
$class
,
$table
);
// Aggregate all the information from all classes in the hierarchy
foreach
(
$class
->
parentClasses
as
$parentClassName
)
{
// Parent class information is already contained in this class
$processedClasses
[
$parentClassName
]
=
true
;
}
foreach
(
$class
->
subClasses
as
$subClassName
)
{
$subClass
=
$this
->
_em
->
getClassMetadata
(
$subClassName
);
$this
->
_gatherColumns
(
$subClass
,
$table
);
$this
->
_gatherRelationsSql
(
$subClass
,
$table
,
$schema
);
$processedClasses
[
$subClassName
]
=
true
;
}
}
else
if
(
$class
->
isInheritanceTypeJoined
())
{
// Add all non-inherited fields as columns
$pkColumns
=
array
();
foreach
(
$class
->
fieldMappings
as
$fieldName
=>
$mapping
)
{
if
(
!
isset
(
$mapping
[
'inherited'
]))
{
$columnName
=
$class
->
getQuotedColumnName
(
$mapping
[
'fieldName'
],
$this
->
_platform
);
$this
->
_gatherColumn
(
$class
,
$mapping
,
$table
);
if
(
$class
->
isIdentifier
(
$fieldName
))
{
$pkColumns
[]
=
$columnName
;
}
}
}
$this
->
_gatherRelationsSql
(
$class
,
$table
,
$schema
);
// Add the discriminator column only to the root table
if
(
$class
->
name
==
$class
->
rootEntityName
)
{
$discrColumnDef
=
$this
->
_getDiscriminatorColumnDefinition
(
$class
,
$table
);
}
else
{
// Add an ID FK column to child tables
/* @var Doctrine\ORM\Mapping\ClassMetadata $class */
$idMapping
=
$class
->
fieldMappings
[
$class
->
identifier
[
0
]];
$this
->
_gatherColumn
(
$class
,
$idMapping
,
$table
);
$columnName
=
$class
->
getQuotedColumnName
(
$class
->
identifier
[
0
],
$this
->
_platform
);
$pkColumns
[]
=
$columnName
;
if
(
$table
->
isIdGeneratorIdentity
())
{
$table
->
setIdGeneratorType
(
\Doctrine\DBAL\Schema\Table
::
ID_NONE
);
}
// Add a FK constraint on the ID column
$table
->
addUnnamedForeignKeyConstraint
(
$this
->
_em
->
getClassMetadata
(
$class
->
rootEntityName
)
->
getQuotedTableName
(
$this
->
_platform
),
array
(
$columnName
),
array
(
$columnName
),
array
(
'onDelete'
=>
'CASCADE'
)
);
}
$table
->
setPrimaryKey
(
$pkColumns
);
}
else
if
(
$class
->
isInheritanceTypeTablePerClass
())
{
throw
DoctrineException
::
notSupported
();
}
else
{
$this
->
_gatherColumns
(
$class
,
$table
);
$this
->
_gatherRelationsSql
(
$class
,
$table
,
$schema
);
}
if
(
isset
(
$class
->
primaryTable
[
'indexes'
]))
{
foreach
(
$class
->
primaryTable
[
'indexes'
]
AS
$indexName
=>
$indexData
)
{
$table
->
addIndex
(
$indexData
[
'columns'
],
$indexName
);
}
}
if
(
isset
(
$class
->
primaryTable
[
'uniqueConstraints'
]))
{
foreach
(
$class
->
primaryTable
[
'uniqueConstraints'
]
AS
$indexName
=>
$indexData
)
{
$table
->
addUniqueIndex
(
$indexData
[
'columns'
],
$indexName
);
}
}
$processedClasses
[
$class
->
name
]
=
true
;
if
(
$class
->
isIdGeneratorSequence
()
&&
$class
->
name
==
$class
->
rootEntityName
)
{
$seqDef
=
$class
->
getSequenceGeneratorDefinition
();
if
(
!
$schema
->
hasSequence
(
$seqDef
[
'sequenceName'
]))
{
$schema
->
createSequence
(
$seqDef
[
'sequenceName'
],
$seqDef
[
'allocationSize'
],
$seqDef
[
'initialValue'
]
);
}
}
}
return
$schema
;
}
/**
* Gets a portable column definition as required by the DBAL for the discriminator
* column of a class.
*
* @param ClassMetadata $class
* @return array The portable column definition of the discriminator column as required by
* the DBAL.
*/
private
function
_getDiscriminatorColumnDefinition
(
$class
,
$table
)
{
$discrColumn
=
$class
->
discriminatorColumn
;
$table
->
createColumn
(
$class
->
getQuotedDiscriminatorColumnName
(
$this
->
_platform
),
$discrColumn
[
'type'
],
array
(
'length'
=>
$discrColumn
[
'length'
],
'notnull'
=>
true
)
);
}
/**
* Gathers the column definitions as required by the DBAL of all field mappings
* found in the given class.
*
* @param ClassMetadata $class
* @param Table $table
* @return array The list of portable column definitions as required by the DBAL.
*/
private
function
_gatherColumns
(
$class
,
$table
)
{
$columns
=
array
();
$pkColumns
=
array
();
foreach
(
$class
->
fieldMappings
as
$fieldName
=>
$mapping
)
{
$column
=
$this
->
_gatherColumn
(
$class
,
$mapping
,
$table
);
if
(
$class
->
isIdentifier
(
$mapping
[
'fieldName'
]))
{
$pkColumns
[]
=
$class
->
getQuotedColumnName
(
$mapping
[
'fieldName'
],
$this
->
_platform
);
}
}
// For now, this is a hack required for single table inheritence, since this method is called
// twice by single table inheritence relations
if
(
!
$table
->
hasIndex
(
'primary'
))
{
$table
->
setPrimaryKey
(
$pkColumns
);
}
return
$columns
;
}
/**
* Creates a column definition as required by the DBAL from an ORM field mapping definition.
*
* @param ClassMetadata $class The class that owns the field mapping.
* @param array $mapping The field mapping.
* @param Table $table
* @return array The portable column definition as required by the DBAL.
*/
private
function
_gatherColumn
(
$class
,
array
$mapping
,
$table
)
{
$columnName
=
$class
->
getQuotedColumnName
(
$mapping
[
'fieldName'
],
$this
->
_platform
);
$columnType
=
$mapping
[
'type'
];
$options
=
array
();
$options
[
'length'
]
=
isset
(
$mapping
[
'length'
])
?
$mapping
[
'length'
]
:
null
;
$options
[
'notnull'
]
=
isset
(
$mapping
[
'nullable'
])
?
!
$mapping
[
'nullable'
]
:
true
;
$options
[
'platformOptions'
]
=
array
();
$options
[
'platformOptions'
][
'version'
]
=
$class
->
isVersioned
&&
$class
->
versionField
==
$mapping
[
'fieldName'
]
?
true
:
false
;
if
(
strtolower
(
$columnType
)
==
'string'
&&
$options
[
'length'
]
===
null
)
{
$options
[
'length'
]
=
255
;
}
if
(
isset
(
$mapping
[
'precision'
]))
{
$options
[
'precision'
]
=
$mapping
[
'precision'
];
}
if
(
isset
(
$mapping
[
'scale'
]))
{
$options
[
'scale'
]
=
$mapping
[
'scale'
];
}
if
(
isset
(
$mapping
[
'default'
]))
{
$options
[
'default'
]
=
$mapping
[
'default'
];
}
if
(
$table
->
hasColumn
(
$columnName
))
{
// required in some inheritence scenarios
$table
->
changeColumn
(
$columnName
,
$options
);
}
else
{
$table
->
createColumn
(
$columnName
,
$columnType
,
$options
);
}
$isUnique
=
isset
(
$mapping
[
'unique'
])
?
$mapping
[
'unique'
]
:
false
;
if
(
$isUnique
)
{
$table
->
addUniqueIndex
(
array
(
$columnName
));
}
}
/**
* Gathers the SQL for properly setting up the relations of the given class.
* This includes the SQL for foreign key constraints and join tables.
*
* @param ClassMetadata $class
* @param array $sql The sequence of SQL statements where any new statements should be appended.
* @param array $columns The list of columns in the class's primary table where any additional
* columns required by relations should be appended.
* @param array $constraints The constraints of the table where any additional constraints
* required by relations should be appended.
* @return void
*/
private
function
_gatherRelationsSql
(
$class
,
$table
,
$schema
)
{
foreach
(
$class
->
associationMappings
as
$fieldName
=>
$mapping
)
{
if
(
isset
(
$class
->
inheritedAssociationFields
[
$fieldName
]))
{
continue
;
}
$foreignClass
=
$this
->
_em
->
getClassMetadata
(
$mapping
->
targetEntityName
);
if
(
$mapping
->
isOneToOne
()
&&
$mapping
->
isOwningSide
)
{
$primaryKeyColumns
=
$uniqueConstraints
=
array
();
// unnecessary for this relation-type
$this
->
_gatherRelationJoinColumns
(
$mapping
->
getJoinColumns
(),
$table
,
$foreignClass
,
$mapping
,
$primaryKeyColumns
,
$uniqueConstraints
);
}
else
if
(
$mapping
->
isOneToMany
()
&&
$mapping
->
isOwningSide
)
{
//... create join table, one-many through join table supported later
throw
DoctrineException
::
notSupported
();
}
else
if
(
$mapping
->
isManyToMany
()
&&
$mapping
->
isOwningSide
)
{
// create join table
$joinTable
=
$mapping
->
getJoinTable
();
$theJoinTable
=
$schema
->
createTable
(
$mapping
->
getQuotedJoinTableName
(
$this
->
_platform
));
$primaryKeyColumns
=
$uniqueConstraints
=
array
();
// Build first FK constraint (relation table => source table)
$this
->
_gatherRelationJoinColumns
(
$joinTable
[
'joinColumns'
],
$theJoinTable
,
$class
,
$mapping
,
$primaryKeyColumns
,
$uniqueConstraints
);
// Build second FK constraint (relation table => target table)
$this
->
_gatherRelationJoinColumns
(
$joinTable
[
'inverseJoinColumns'
],
$theJoinTable
,
$foreignClass
,
$mapping
,
$primaryKeyColumns
,
$uniqueConstraints
);
foreach
(
$uniqueConstraints
AS
$indexName
=>
$unique
)
{
$theJoinTable
->
addUniqueIndex
(
$unique
[
'columns'
],
is_numeric
(
$indexName
)
?
null
:
$indexName
);
}
$theJoinTable
->
setPrimaryKey
(
$primaryKeyColumns
);
}
}
}
/**
* Gather columns and fk constraints that are required for one part of relationship.
*
* @param array $joinColumns
* @param \Doctrine\DBAL\Schema\Table $theJoinTable
* @param ClassMetadata $class
* @param \Doctrine\ORM\Mapping\AssociationMapping $mapping
* @param array $primaryKeyColumns
* @param array $uniqueConstraints
*/
private
function
_gatherRelationJoinColumns
(
$joinColumns
,
$theJoinTable
,
$class
,
$mapping
,
&
$primaryKeyColumns
,
&
$uniqueConstraints
)
{
$localColumns
=
array
();
$foreignColumns
=
array
();
$fkOptions
=
array
();
foreach
(
$joinColumns
as
$joinColumn
)
{
// Note that this thing might be quoted, i.e. `foo`, [foo], ...
$columnName
=
$mapping
->
getQuotedJoinColumnName
(
$joinColumn
[
'name'
],
$this
->
_platform
);
if
(
!
$class
->
hasField
(
$class
->
getFieldName
(
$joinColumn
[
'referencedColumnName'
])))
{
throw
new
\Doctrine\Common\DoctrineException
(
"Column name `"
.
$joinColumn
[
'referencedColumnName'
]
.
"` referenced for relation from "
.
"
$mapping->sourceEntityName
towards
$mapping->targetEntityName
does not exist."
);
}
$primaryKeyColumns
[]
=
$columnName
;
$localColumns
[]
=
$columnName
;
$foreignColumns
[]
=
$joinColumn
[
'referencedColumnName'
];
if
(
!
$theJoinTable
->
hasColumn
(
$joinColumn
[
'name'
]))
{
// Only add the column to the table if it does not exist already.
// It might exist already if the foreign key is mapped into a regular
// property as well.
$theJoinTable
->
createColumn
(
$columnName
,
$class
->
getTypeOfColumn
(
$joinColumn
[
'referencedColumnName'
]),
array
(
'notnull'
=>
false
)
);
}
if
(
isset
(
$joinColumn
[
'unique'
])
&&
$joinColumn
[
'unique'
]
==
true
)
{
$uniqueConstraints
[]
=
array
(
'columns'
=>
$columnName
);
}
if
(
isset
(
$joinColumn
[
'onUpdate'
]))
{
$fkOptions
[
'onUpdate'
]
=
$joinColumn
[
'onUpdate'
];
}
if
(
isset
(
$joinColumn
[
'onDelete'
]))
{
$fkOptions
[
'onDelete'
]
=
$joinColumn
[
'onDelete'
];
}
}
$theJoinTable
->
addUnnamedForeignKeyConstraint
(
$class
->
getQuotedTableName
(
$this
->
_platform
),
$localColumns
,
$foreignColumns
,
$fkOptions
);
}
/**
* Drops the database schema for the given classes.
*
* In any way when an exception is thrown it is supressed since drop was
* issued for all classes of the schema and some probably just don't exist.
*
* @param array $classes
* @param string $mode
* @return void
*/
public
function
dropSchema
(
array
$classes
,
$mode
=
self
::
DROP_METADATA
)
{
$dropSchemaSql
=
$this
->
getDropSchemaSql
(
$classes
,
$mode
);
$conn
=
$this
->
_em
->
getConnection
();
foreach
(
$dropSchemaSql
as
$sql
)
{
$conn
->
execute
(
$sql
);
}
}
/**
* Gets the SQL needed to drop the database schema for the given classes.
*
* @param array $classes
* @param string $mode
* @return array
*/
public
function
getDropSchemaSql
(
array
$classes
)
{
$sm
=
$this
->
_em
->
getConnection
()
->
getSchemaManager
();
$schema
=
$sm
->
createSchema
();
$visitor
=
new
\Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector
(
$this
->
_platform
);
/* @var $schema \Doctrine\DBAL\Schema\Schema */
$schema
->
visit
(
$visitor
);
return
$visitor
->
getQueries
();
}
/**
* Drop all tables of the database connection.
*
* @return array
*/
private
function
_getDropSchemaTablesDatabaseMode
(
$classes
)
{
$conn
=
$this
->
_em
->
getConnection
();
$sm
=
$conn
->
getSchemaManager
();
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$allTables
=
$sm
->
listTables
();
$orderedTables
=
$this
->
_getDropSchemaTablesMetadataMode
(
$classes
);
foreach
(
$allTables
AS
$tableName
)
{
if
(
!
in_array
(
$tableName
,
$orderedTables
))
{
$orderedTables
[]
=
$tableName
;
}
}
return
$orderedTables
;
}
private
function
_getDropSchemaTablesMetadataMode
(
array
$classes
)
{
$orderedTables
=
array
();
$commitOrder
=
$this
->
_getCommitOrder
(
$classes
);
$associationTables
=
$this
->
_getAssociationTables
(
$commitOrder
);
// Drop association tables first
foreach
(
$associationTables
as
$associationTable
)
{
$orderedTables
[]
=
$associationTable
;
}
// Drop tables in reverse commit order
for
(
$i
=
count
(
$commitOrder
)
-
1
;
$i
>=
0
;
--
$i
)
{
$class
=
$commitOrder
[
$i
];
if
((
$class
->
isInheritanceTypeSingleTable
()
&&
$class
->
name
!=
$class
->
rootEntityName
)
||
$class
->
isMappedSuperclass
)
{
continue
;
}
$orderedTables
[]
=
$class
->
getTableName
();
}
//TODO: Drop other schema elements, like sequences etc.
return
$orderedTables
;
}
/**
* Updates the database schema of the given classes by comparing the ClassMetadata
* instances to the current database schema that is inspected.
*
* @param array $classes
* @return void
*/
public
function
updateSchema
(
array
$classes
,
$saveMode
=
false
)
{
$updateSchemaSql
=
$this
->
getUpdateSchemaSql
(
$classes
,
$saveMode
);
$conn
=
$this
->
_em
->
getConnection
();
foreach
(
$updateSchemaSql
as
$sql
)
{
$conn
->
execute
(
$sql
);
}
}
/**
* Gets the sequence of SQL statements that need to be performed in order
* to bring the given class mappings in-synch with the relational schema.
*
* @param array $classes The classes to consider.
* @return array The sequence of SQL statements.
*/
public
function
getUpdateSchemaSql
(
array
$classes
,
$saveMode
=
false
)
{
$sm
=
$this
->
_em
->
getConnection
()
->
getSchemaManager
();
$fromSchema
=
$sm
->
createSchema
();
$toSchema
=
$this
->
getSchemaFromMetadata
(
$classes
);
$comparator
=
new
\Doctrine\DBAL\Schema\Comparator
();
$schemaDiff
=
$comparator
->
compare
(
$fromSchema
,
$toSchema
);
if
(
$saveMode
)
{
return
$schemaDiff
->
toSaveSql
(
$this
->
_platform
);
}
else
{
return
$schemaDiff
->
toSql
(
$this
->
_platform
);
}
}
private
function
_getCommitOrder
(
array
$classes
)
{
$calc
=
new
CommitOrderCalculator
;
// Calculate dependencies
foreach
(
$classes
as
$class
)
{
$calc
->
addClass
(
$class
);
foreach
(
$class
->
associationMappings
as
$assoc
)
{
if
(
$assoc
->
isOwningSide
)
{
$targetClass
=
$this
->
_em
->
getClassMetadata
(
$assoc
->
targetEntityName
);
if
(
!
$calc
->
hasClass
(
$targetClass
->
name
))
{
$calc
->
addClass
(
$targetClass
);
}
// add dependency ($targetClass before $class)
$calc
->
addDependency
(
$targetClass
,
$class
);
}
}
}
return
$calc
->
getCommitOrder
();
}
private
function
_getAssociationTables
(
array
$classes
)
{
$associationTables
=
array
();
foreach
(
$classes
as
$class
)
{
foreach
(
$class
->
associationMappings
as
$assoc
)
{
if
(
$assoc
->
isOwningSide
&&
$assoc
->
isManyToMany
())
{
$associationTables
[]
=
$assoc
->
joinTable
[
'name'
];
}
}
}
return
$associationTables
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment