Merge branch 'master' of http://github.com/doctrine/doctrine2
This commit is contained in:
commit
fc7224f73e
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
build.properties
|
||||
build/
|
||||
logs/
|
||||
reports/
|
||||
dist/
|
||||
download/
|
||||
lib/api/
|
||||
lib/Doctrine/Common
|
||||
lib/Doctrine/DBAL
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "lib/vendor/doctrine-common"]
|
||||
path = lib/vendor/doctrine-common
|
||||
url = git://github.com/doctrine/common.git
|
||||
[submodule "lib/vendor/doctrine-dbal"]
|
||||
path = lib/vendor/doctrine-dbal
|
||||
url = git://github.com/doctrine/dbal.git
|
39
COPYRIGHT
39
COPYRIGHT
@ -1,39 +0,0 @@
|
||||
Copyrights
|
||||
----------
|
||||
|
||||
Doctrine
|
||||
--------
|
||||
|
||||
Doctrine is a Object Relational Mapper built from scratch with PHP5. It contains a few ports of other popular PHP classes/libraries.
|
||||
|
||||
Url: http://www.doctrine-project.org
|
||||
Copyright: 2005-2009 Konsta Vesterinen
|
||||
License: LGPL - see LICENSE file
|
||||
|
||||
symfony
|
||||
-------
|
||||
|
||||
Doctrine contains ports of a few symfony classes/libraries
|
||||
|
||||
Url: http://www.symfony-project.org
|
||||
Copyright: Fabien Potencier
|
||||
License: MIT - see LICENSE file
|
||||
|
||||
Zend Framework
|
||||
--------------
|
||||
|
||||
Doctrine contains ports of a few Zend components and has borrowed concepts and ideas from the Zend Framework project.
|
||||
|
||||
Url: http://framework.zend.com
|
||||
Copyright: Copyright © 2006-2009 by Zend Technologies, All rights reserved.
|
||||
License: New BSD License
|
||||
|
||||
eZ Components
|
||||
------------
|
||||
|
||||
Doctrine SchemaTool, Platforms and SchemaManagers borrow ideas and concepts
|
||||
from ezcDatabaseSchema.
|
||||
|
||||
Url: http://www.ezcomponents.org
|
||||
License: New BSD License
|
||||
Copyright: Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
|
14
README.markdown
Normal file
14
README.markdown
Normal file
@ -0,0 +1,14 @@
|
||||
# Doctrine 2 ORM
|
||||
|
||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.0+ that provides transparent persistence
|
||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
|
||||
inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
|
||||
without requiring unnecessary code duplication.
|
||||
|
||||
More resources:
|
||||
|
||||
* [Website](http://www.doctrine-project.org)
|
||||
* [Documentation](http://www.doctrine-project.org/projects/orm/2.0/docs/reference/introduction/en)
|
||||
* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DDC)
|
||||
* [Downloads](http://github.com/doctrine/doctrine2/downloads)
|
@ -1,3 +1,13 @@
|
||||
# Update from 2.0-BETA2 to 2.0-BETA3
|
||||
|
||||
## Default Allocation Size for Sequences
|
||||
|
||||
The default allocation size for sequences has been changed from 10 to 1. This step was made
|
||||
to not cause confusion with users and also because it is partly some kind of premature optimization.
|
||||
|
||||
# Update from 2.0-BETA1 to 2.0-BETA2
|
||||
|
||||
There are no backwards incompatible changes in this release.
|
||||
|
||||
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
require_once 'Doctrine/Common/ClassLoader.php';
|
||||
|
||||
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', __DIR__ . '/../lib');
|
||||
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
|
||||
$classLoader->register();
|
||||
|
||||
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', __DIR__ . '/../lib/vendor');
|
||||
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', 'Doctrine');
|
||||
$classLoader->register();
|
||||
|
||||
$configFile = getcwd() . DIRECTORY_SEPARATOR . 'cli-config.php';
|
||||
@ -30,7 +30,7 @@ if (file_exists($configFile)) {
|
||||
|
||||
$helperSet = ($helperSet) ?: new \Symfony\Components\Console\Helper\HelperSet();
|
||||
|
||||
$cli = new \Symfony\Components\Console\Application('Doctrine Command Line Interface', Doctrine\Common\Version::VERSION);
|
||||
$cli = new \Symfony\Components\Console\Application('Doctrine Command Line Interface', Doctrine\ORM\Version::VERSION);
|
||||
$cli->setCatchExceptions(true);
|
||||
$cli->setHelperSet($helperSet);
|
||||
$cli->addCommands(array(
|
||||
|
@ -1,6 +1,5 @@
|
||||
version_name=2.0.0-ALPHA2
|
||||
version=2.0.0
|
||||
stability=alpha
|
||||
version=2.0.0BETA2
|
||||
stability=beta
|
||||
build.dir=build
|
||||
dist.dir=dist
|
||||
report.dir=reports
|
||||
|
143
build.xml
143
build.xml
@ -5,18 +5,17 @@
|
||||
-->
|
||||
|
||||
<project name="Doctrine2" default="build" basedir=".">
|
||||
|
||||
<taskdef classname="NativePhpunitTask" classpath="./tests/" name="nativephpunit" />
|
||||
<taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
|
||||
<taskdef classname="NativePhpunitTask" classpath="./tools/" name="nativephpunit" />
|
||||
|
||||
<property file="build.properties" />
|
||||
|
||||
<!--
|
||||
|
||||
<!--
|
||||
Fileset for artifacts shared across all distributed packages.
|
||||
-->
|
||||
<fileset id="shared-artifacts" dir=".">
|
||||
<include name="LICENSE"/>
|
||||
<include name="COPYRIGHT"/>
|
||||
<include name="CHANGELOG"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
@ -27,41 +26,37 @@
|
||||
<include name="doctrine.php"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine Common package.
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine Common dependency.
|
||||
-->
|
||||
<fileset id="common-sources" dir="./lib">
|
||||
<fileset id="common-sources" dir="./lib/vendor/doctrine-common/lib">
|
||||
<include name="Doctrine/Common/**"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine DBAL package.
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine DBAL dependency.
|
||||
-->
|
||||
<fileset id="dbal-sources" dir="./lib">
|
||||
<fileset id="dbal-sources" dir="./lib/vendor/doctrine-dbal/lib">
|
||||
<include name="Doctrine/DBAL/**"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine ORM package.
|
||||
|
||||
<!--
|
||||
Fileset for the sources of the Doctrine ORM.
|
||||
-->
|
||||
<fileset id="orm-sources" dir="./lib">
|
||||
<include name="Doctrine/ORM/**"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
Fileset for the Doctrine ORM tools + sandbox.
|
||||
|
||||
<!--
|
||||
Fileset for source of the Symfony YAML and Console components.
|
||||
-->
|
||||
<fileset id="orm-tools" dir=".">
|
||||
<include name="tools/sandbox/Entities"/>
|
||||
<include name="tools/sandbox/xml"/>
|
||||
<include name="tools/sandbox/yaml"/>
|
||||
<include name="tools/sandbox/cli-config.php"/>
|
||||
<include name="tools/sandbox/config.php"/>
|
||||
<include name="tools/sandbox/doctrine"/>
|
||||
<include name="tools/sandbox/doctrine.php"/>
|
||||
<include name="tools/sandbox/index.php"/>
|
||||
<fileset id="symfony-sources" dir="./lib/vendor">
|
||||
<include name="Symfony/Components/**"/>
|
||||
</fileset>
|
||||
|
||||
<!--
|
||||
Clean the directory for the next build.
|
||||
-->
|
||||
<target name="clean">
|
||||
<available file="./build.properties" property="build_properties_exist" value="true"/>
|
||||
<fail unless="build_properties_exist" message="The build.properties file is missing." />
|
||||
@ -71,6 +66,9 @@
|
||||
<delete dir="${report.dir}" includeemptydirs="true" />
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Prepare the new build directories after cleaning
|
||||
-->
|
||||
<target name="prepare" depends="clean">
|
||||
<echo msg="Creating build directory: ${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
@ -82,46 +80,31 @@
|
||||
<mkdir dir="${report.dir}/tests"/>
|
||||
</target>
|
||||
|
||||
<target name="build-common">
|
||||
<copy todir="${build.dir}/common">
|
||||
<fileset refid="shared-artifacts"/>
|
||||
</copy>
|
||||
<copy todir="${build.dir}/common/DoctrineCommon-${version}">
|
||||
<fileset refid="common-sources"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build-dbal">
|
||||
<copy todir="${build.dir}/dbal">
|
||||
<fileset refid="shared-artifacts"/>
|
||||
</copy>
|
||||
<copy todir="${build.dir}/dbal/DoctrineDBAL-${version}">
|
||||
<fileset refid="common-sources"/>
|
||||
<fileset refid="dbal-sources"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Builds all packages, preparing them for distribution.
|
||||
<!--
|
||||
Builds ORM package, preparing it for distribution.
|
||||
-->
|
||||
<target name="build-orm" depends="test, build-common, build-dbal">
|
||||
<target name="build-orm" depends="test">
|
||||
<copy todir="${build.dir}/orm">
|
||||
<fileset refid="shared-artifacts"/>
|
||||
<fileset refid="orm-tools"/>
|
||||
</copy>
|
||||
<copy todir="${build.dir}/orm/DoctrineORM-${version}">
|
||||
<copy todir="${build.dir}/orm">
|
||||
<fileset refid="common-sources"/>
|
||||
<fileset refid="dbal-sources"/>
|
||||
<fileset refid="orm-sources"/>
|
||||
</copy>
|
||||
<copy todir="${build.dir}/orm/DoctrineORM-${version}/bin">
|
||||
<copy todir="${build.dir}/orm/Doctrine">
|
||||
<fileset refid="symfony-sources"/>
|
||||
</copy>
|
||||
<copy todir="${build.dir}/orm/bin">
|
||||
<fileset refid="bin-scripts"/>
|
||||
</copy>
|
||||
<exec command="sed 's/${version}-DEV/${version}/' ${build.dir}/orm/Doctrine/ORM/Version.php > ${build.dir}/orm/Doctrine/ORM/Version2.php" passthru="true" />
|
||||
<exec command="mv ${build.dir}/orm/Doctrine/ORM/Version2.php ${build.dir}/orm/Doctrine/ORM/Version.php" passthru="true" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="build" depends="test, build-orm"/>
|
||||
|
||||
<!--
|
||||
|
||||
<!--
|
||||
Runs the full test suite.
|
||||
-->
|
||||
<target name="test" depends="prepare">
|
||||
@ -142,7 +125,6 @@
|
||||
|
||||
<nativephpunit testfile="./tests/Doctrine/Tests/ORM/Performance/AllTests.php" testdirectory="./tests" haltonfailure="false" haltonerror="false" />
|
||||
<tstamp/>
|
||||
<!--<svnlastrevision svnpath="${svn.path}" workingcopy="." propertyname="svn.lastrevision"/>-->
|
||||
<copy file="${build.dir}/logs/testsuites.xml" tofile="${log.archive.dir}/latest/log.xml" overwrite="true"/>
|
||||
|
||||
<if><equals arg1="${test.pmd_reports}" arg2="1" />
|
||||
@ -156,51 +138,13 @@
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Builds distributable PEAR packages.
|
||||
-->
|
||||
<target name="build-packages" depends="build-orm">
|
||||
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/common/DoctrineCommon-${version}">
|
||||
<name>DoctrineCommon</name>
|
||||
<summary>Common Doctrine code</summary>
|
||||
<channel>pear.doctrine-project.org</channel>
|
||||
<description>The Doctrine Common package contains shared code between the other packages.</description>
|
||||
<lead user="jwage" name="Jonathan H. Wage" email="jonwage@gmail.com" />
|
||||
<lead user="guilhermeblanco" name="Guilherme Blanco" email="guilhermeblanco@gmail.com" />
|
||||
<lead user="romanb" name="Roman Borschel" email="roman@code-factory.org" />
|
||||
<license>LGPL</license>
|
||||
<version release="${version}" api="${version}" />
|
||||
<stability release="${stability}" api="${stability}" />
|
||||
<notes>-</notes>
|
||||
<dependencies>
|
||||
<php minimum_version="5.3.0" />
|
||||
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
|
||||
</dependencies>
|
||||
</d51pearpkg2>
|
||||
<tar destfile="${dist.dir}/DoctrineCommon-${version_name}.tgz" basedir="${build.dir}/common" compression="gzip" />
|
||||
|
||||
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/dbal/DoctrineDBAL-${version}">
|
||||
<name>DoctrineDBAL</name>
|
||||
<summary>Doctrine Database Abstraction Layer</summary>
|
||||
<channel>pear.doctrine-project.org</channel>
|
||||
<description>The Doctrine DBAL package is the database abstraction layer used to power the ORM package.</description>
|
||||
<lead user="jwage" name="Jonathan H. Wage" email="jonwage@gmail.com" />
|
||||
<lead user="guilhermeblanco" name="Guilherme Blanco" email="guilhermeblanco@gmail.com" />
|
||||
<lead user="romanb" name="Roman Borschel" email="roman@code-factory.org" />
|
||||
<license>LGPL</license>
|
||||
<version release="${version}" api="${version}" />
|
||||
<stability release="${stability}" api="${stability}" />
|
||||
<notes>-</notes>
|
||||
<dependencies>
|
||||
<php minimum_version="5.3.0" />
|
||||
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
|
||||
</dependencies>
|
||||
</d51pearpkg2>
|
||||
<tar destfile="${dist.dir}/DoctrineDBAL-${version_name}.tgz" basedir="${build.dir}/dbal" compression="gzip" />
|
||||
|
||||
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/orm/DoctrineORM-${version}">
|
||||
<target name="build-packages" depends="build">
|
||||
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/orm">
|
||||
<name>DoctrineORM</name>
|
||||
<summary>Doctrine Object Relationl Mapper</summary>
|
||||
<summary>Doctrine Object Relational Mapper</summary>
|
||||
<channel>pear.doctrine-project.org</channel>
|
||||
<description>The Doctrine ORM package is the primary package containing the object relational mapper.</description>
|
||||
<lead user="jwage" name="Jonathan H. Wage" email="jonwage@gmail.com" />
|
||||
@ -223,6 +167,7 @@
|
||||
<install as="doctrine.php" name="bin/doctrine.php" />
|
||||
</release>
|
||||
</d51pearpkg2>
|
||||
<tar destfile="${dist.dir}/DoctrineORM-${version_name}.tgz" basedir="${build.dir}/orm" compression="gzip" />
|
||||
<exec command="pear package" dir="${build.dir}/orm" passthru="true" />
|
||||
<exec command="mv DoctrineORM-${version}.tgz ../../dist" dir="${build.dir}/orm" passthru="true" />
|
||||
</target>
|
||||
</project>
|
||||
</project>
|
@ -124,6 +124,8 @@
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="version" type="xs:boolean" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:attribute name="precision" type="xs:integer" use="optional" />
|
||||
<xs:attribute name="scale" type="xs:integer" use="optional" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="discriminator-column">
|
||||
@ -135,7 +137,7 @@
|
||||
|
||||
<xs:complexType name="unique-constraint">
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
|
||||
<xs:attribute name="columns" type="xs:NMTOKENS" use="required"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="unique-constraints">
|
||||
|
92
jpgraph.php
92
jpgraph.php
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
// If you dont have jpgraph, you need to download it from:
|
||||
// http://www.aditus.nu/jpgraph/jpdownload.php
|
||||
|
||||
$jpgraphPath = '../lib/jpgraph-3.0.3/src'; // put the path to your jpgraph install here
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
require_once "$jpgraphPath/jpgraph.php";
|
||||
require_once "$jpgraphPath/jpgraph_line.php";
|
||||
|
||||
$logsPath = 'logs/';
|
||||
|
||||
$revisions = array();
|
||||
$graphs = array();
|
||||
|
||||
if (isset($_POST['test'])) {
|
||||
list($testsuite, $testcase) = explode('#', $_POST['test']);
|
||||
}
|
||||
|
||||
$items = scandir($logsPath);
|
||||
foreach ($items as $item) {
|
||||
if ($item[0] != '.') {
|
||||
$revisions[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($revisions as $rev) {
|
||||
$xml = simplexml_load_file($logsPath . $rev . '/log.xml');
|
||||
foreach ($xml->testsuite as $suite) {
|
||||
foreach ($suite->testcase as $test) {
|
||||
if (stripos((string)$suite['name'], 'performance') !== false || stripos((string)$test['name'], 'performance') !== false) {
|
||||
$name = (string)$suite['name'] . '#' . (string)$test['name'];
|
||||
$graphs[$name][] = (double)$test['time'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($testsuite) && isset($testcase)) {
|
||||
$graphName = $testsuite . '#' . $testcase;
|
||||
$graphData = $graphs[$graphName];
|
||||
|
||||
// Create the graph. These two calls are always required
|
||||
$graph = new Graph(650,250);
|
||||
|
||||
//$graph->SetScale('intint');
|
||||
$graph->SetScale('textlin');
|
||||
$graph->yaxis->scale->SetAutoMin(0);
|
||||
|
||||
$graph->title->Set($testsuite);
|
||||
$graph->subtitle->Set($testcase);
|
||||
|
||||
$graph->xaxis->title->Set('revision');
|
||||
$graph->yaxis->title->Set('seconds');
|
||||
$graph->SetMargin(100, 100, 50, 50);
|
||||
|
||||
// Create the linear plot
|
||||
$lineplot = new LinePlot($graphData);
|
||||
$lineplot->SetColor('blue');
|
||||
|
||||
$graph->xaxis->SetTickLabels($revisions);
|
||||
|
||||
// Add the plot to the graph
|
||||
$graph->Add($lineplot);
|
||||
|
||||
// Display the graph
|
||||
$graph->Stroke();
|
||||
} else {
|
||||
|
||||
echo '<html><head></head><body>';
|
||||
echo 'Pick a test and click "show":<br/>';
|
||||
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '">';
|
||||
|
||||
echo '<select name="test">';
|
||||
|
||||
foreach ($graphs as $name => $data) {
|
||||
echo '<option value="' . $name . '">' . $name . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
|
||||
echo '<button type="submit">Show</button>';
|
||||
|
||||
echo '</form>';
|
||||
echo '</body></html>';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
<?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\Common\Annotations;
|
||||
|
||||
/**
|
||||
* Annotations class
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Annotation
|
||||
{
|
||||
/**
|
||||
* Value property. Common among all derived classes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $data Key-value for properties to be defined in this class
|
||||
*/
|
||||
public final function __construct(array $data)
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for unknown property accessor in Annotation class.
|
||||
*
|
||||
* @param string $name Unknown property name
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
throw new \BadMethodCallException(
|
||||
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for unknown property mutator in Annotation class.
|
||||
*
|
||||
* @param string $name Unkown property name
|
||||
* @param mixed $value Property value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
throw new \BadMethodCallException(
|
||||
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
|
||||
);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
<?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\Common\Annotations;
|
||||
|
||||
/**
|
||||
* Description of AnnotationException
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class AnnotationException extends \Exception
|
||||
{
|
||||
/**
|
||||
* Creates a new AnnotationException describing a Syntax error.
|
||||
*
|
||||
* @param string $message Exception message
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function syntaxError($message)
|
||||
{
|
||||
return new self('[Syntax Error] ' . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing a Semantical error.
|
||||
*
|
||||
* @param string $message Exception message
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function semanticalError($message)
|
||||
{
|
||||
return new self('[Semantical Error] ' . $message);
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common\Annotations;
|
||||
|
||||
use \ReflectionClass,
|
||||
\ReflectionMethod,
|
||||
\ReflectionProperty,
|
||||
Doctrine\Common\Cache\Cache;
|
||||
|
||||
/**
|
||||
* A reader for docblock annotations.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class AnnotationReader
|
||||
{
|
||||
/**
|
||||
* Cache salt
|
||||
*
|
||||
* @var string
|
||||
* @static
|
||||
*/
|
||||
private static $CACHE_SALT = '@<Annot>';
|
||||
|
||||
/**
|
||||
* Annotations Parser
|
||||
*
|
||||
* @var Doctrine\Common\Annotations\Parser
|
||||
*/
|
||||
private $_parser;
|
||||
|
||||
/**
|
||||
* Cache mechanism to store processed Annotations
|
||||
*
|
||||
* @var Doctrine\Common\Cache\Cache
|
||||
*/
|
||||
private $_cache;
|
||||
|
||||
/**
|
||||
* Constructor. Initializes a new AnnotationReader that uses the given Cache provider.
|
||||
*
|
||||
* @param Cache $cache The cache provider to use. If none is provided, ArrayCache is used.
|
||||
*/
|
||||
public function __construct(Cache $cache = null)
|
||||
{
|
||||
$this->_parser = new Parser;
|
||||
$this->_cache = $cache ?: new \Doctrine\Common\Cache\ArrayCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default namespace that the AnnotationReader should assume for annotations
|
||||
* with not fully qualified names.
|
||||
*
|
||||
* @param string $defaultNamespace
|
||||
*/
|
||||
public function setDefaultAnnotationNamespace($defaultNamespace)
|
||||
{
|
||||
$this->_parser->setDefaultAnnotationNamespace($defaultNamespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alias for an annotation namespace.
|
||||
*
|
||||
* @param $namespace
|
||||
* @param $alias
|
||||
*/
|
||||
public function setAnnotationNamespaceAlias($namespace, $alias)
|
||||
{
|
||||
$this->_parser->setAnnotationNamespaceAlias($namespace, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a class.
|
||||
*
|
||||
* @param string|ReflectionClass $class The name or ReflectionClass of the class from which
|
||||
* the class annotations should be read.
|
||||
* @return array An array of Annotations.
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
$cacheKey = $class->getName() . self::$CACHE_SALT;
|
||||
|
||||
// Attempt to grab data from cache
|
||||
if (($data = $this->_cache->fetch($cacheKey)) !== false) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$annotations = $this->_parser->parse($class->getDocComment(), 'class ' . $class->getName());
|
||||
$this->_cache->save($cacheKey, $annotations, null);
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a class annotation.
|
||||
*
|
||||
* @param $class
|
||||
* @param string $annotation The name of the annotation.
|
||||
* @return The Annotation or NULL, if the requested annotation does not exist.
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotation)
|
||||
{
|
||||
$annotations = $this->getClassAnnotations($class);
|
||||
|
||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a property.
|
||||
*
|
||||
* @param string|ReflectionClass $class The name or ReflectionClass of the class that owns the property.
|
||||
* @param string|ReflectionProperty $property The name or ReflectionProperty of the property
|
||||
* from which the annotations should be read.
|
||||
* @return array An array of Annotations.
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$cacheKey = $property->getDeclaringClass()->getName() . '$' . $property->getName() . self::$CACHE_SALT;
|
||||
|
||||
// Attempt to grab data from cache
|
||||
if (($data = $this->_cache->fetch($cacheKey)) !== false) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$context = 'property ' . $property->getDeclaringClass()->getName() . "::\$" . $property->getName();
|
||||
$annotations = $this->_parser->parse($property->getDocComment(), $context);
|
||||
$this->_cache->save($cacheKey, $annotations, null);
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property annotation.
|
||||
*
|
||||
* @param ReflectionProperty $property
|
||||
* @param string $annotation The name of the annotation.
|
||||
* @return The Annotation or NULL, if the requested annotation does not exist.
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotation)
|
||||
{
|
||||
$annotations = $this->getPropertyAnnotations($property);
|
||||
|
||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a method.
|
||||
*
|
||||
* @param string|ReflectionClass $class The name or ReflectionClass of the class that owns the method.
|
||||
* @param string|ReflectionMethod $property The name or ReflectionMethod of the method from which
|
||||
* the annotations should be read.
|
||||
* @return array An array of Annotations.
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$cacheKey = $method->getDeclaringClass()->getName() . '#' . $method->getName() . self::$CACHE_SALT;
|
||||
|
||||
// Attempt to grab data from cache
|
||||
if (($data = $this->_cache->fetch($cacheKey)) !== false) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$context = 'method ' . $method->getDeclaringClass()->getName() . '::' . $method->getName() . '()';
|
||||
$annotations = $this->_parser->parse($method->getDocComment(), $context);
|
||||
$this->_cache->save($cacheKey, $annotations, null);
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a method annotation.
|
||||
*
|
||||
* @param ReflectionMethod $method
|
||||
* @param string $annotation The name of the annotation.
|
||||
* @return The Annotation or NULL, if the requested annotation does not exist.
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotation)
|
||||
{
|
||||
$annotations = $this->getMethodAnnotations($method);
|
||||
|
||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
<?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\Common\Annotations;
|
||||
|
||||
/**
|
||||
* Simple lexer for docblock annotations.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Lexer extends \Doctrine\Common\Lexer
|
||||
{
|
||||
const T_NONE = 1;
|
||||
const T_IDENTIFIER = 2;
|
||||
const T_INTEGER = 3;
|
||||
const T_STRING = 4;
|
||||
const T_FLOAT = 5;
|
||||
|
||||
const T_AT = 101;
|
||||
const T_CLOSE_CURLY_BRACES = 102;
|
||||
const T_CLOSE_PARENTHESIS = 103;
|
||||
const T_COMMA = 104;
|
||||
const T_EQUALS = 105;
|
||||
const T_FALSE = 106;
|
||||
const T_NAMESPACE_SEPARATOR = 107;
|
||||
const T_OPEN_CURLY_BRACES = 108;
|
||||
const T_OPEN_PARENTHESIS = 109;
|
||||
const T_TRUE = 110;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function getCatchablePatterns()
|
||||
{
|
||||
return array(
|
||||
'[a-z_][a-z0-9_:]*',
|
||||
'(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?',
|
||||
'"(?:[^"]|"")*"'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function getNonCatchablePatterns()
|
||||
{
|
||||
return array('\s+', '\*+', '(.)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function _getType(&$value)
|
||||
{
|
||||
$type = self::T_NONE;
|
||||
$newVal = $this->_getNumeric($value);
|
||||
|
||||
// Checking numeric value
|
||||
if ($newVal !== false) {
|
||||
$value = $newVal;
|
||||
|
||||
return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
|
||||
? self::T_FLOAT : self::T_INTEGER;
|
||||
}
|
||||
|
||||
if ($value[0] === '"') {
|
||||
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
|
||||
|
||||
return self::T_STRING;
|
||||
} else {
|
||||
switch (strtolower($value)) {
|
||||
case '@':
|
||||
return self::T_AT;
|
||||
|
||||
case ',':
|
||||
return self::T_COMMA;
|
||||
|
||||
case '(':
|
||||
return self::T_OPEN_PARENTHESIS;
|
||||
|
||||
case ')':
|
||||
return self::T_CLOSE_PARENTHESIS;
|
||||
|
||||
case '{':
|
||||
return self::T_OPEN_CURLY_BRACES;
|
||||
|
||||
case '}': return self::T_CLOSE_CURLY_BRACES;
|
||||
case '=':
|
||||
return self::T_EQUALS;
|
||||
|
||||
case '\\':
|
||||
return self::T_NAMESPACE_SEPARATOR;
|
||||
|
||||
case 'true':
|
||||
return self::T_TRUE;
|
||||
|
||||
case 'false':
|
||||
return self::T_FALSE;
|
||||
|
||||
default:
|
||||
if (ctype_alpha($value[0]) || $value[0] === '_') {
|
||||
return self::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a value is numeric or not
|
||||
*
|
||||
* @param mixed $value Value to be inspected
|
||||
* @return boolean|integer|float Processed value
|
||||
*/
|
||||
private function _getNumeric($value)
|
||||
{
|
||||
if ( ! is_scalar($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking for valid numeric numbers: 1.234, -1.234e-2
|
||||
if (is_numeric($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,445 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common\Annotations;
|
||||
|
||||
/**
|
||||
* A simple parser for docblock annotations.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* Tags that are stripped prior to parsing in order to reduce parsing overhead.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_strippedInlineTags = array(
|
||||
"{@example", "{@id", "{@internal", "{@inheritdoc",
|
||||
"{@link", "{@source", "{@toc", "{@tutorial", "*/"
|
||||
);
|
||||
|
||||
/**
|
||||
* The lexer.
|
||||
*
|
||||
* @var Doctrine\Common\Annotations\Lexer
|
||||
*/
|
||||
private $_lexer;
|
||||
|
||||
/**
|
||||
* Flag to control if the current Annotation is nested or not.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_isNestedAnnotation = false;
|
||||
|
||||
/**
|
||||
* Default namespace for Annotations.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_defaultAnnotationNamespace = '';
|
||||
|
||||
/**
|
||||
* Hashmap to store namespace aliases.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_namespaceAliases = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_context = '';
|
||||
|
||||
/**
|
||||
* Constructs a new AnnotationParser.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_lexer = new Lexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default namespace that is assumed for an annotation that does not
|
||||
* define a namespace prefix.
|
||||
*
|
||||
* @param $defaultNamespace
|
||||
*/
|
||||
public function setDefaultAnnotationNamespace($defaultNamespace)
|
||||
{
|
||||
$this->_defaultAnnotationNamespace = $defaultNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alias for an annotation namespace.
|
||||
*
|
||||
* @param $namespace
|
||||
* @param $alias
|
||||
*/
|
||||
public function setAnnotationNamespaceAlias($namespace, $alias)
|
||||
{
|
||||
$this->_namespaceAliases[$alias] = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given docblock string for annotations.
|
||||
*
|
||||
* @param string $docBlockString
|
||||
* @param string $context
|
||||
* @return array Array of Annotations. If no annotations are found, an empty array is returned.
|
||||
*/
|
||||
public function parse($docBlockString, $context='')
|
||||
{
|
||||
$this->_context = $context;
|
||||
|
||||
// Strip out some known inline tags.
|
||||
$input = str_replace(self::$_strippedInlineTags, '', $docBlockString);
|
||||
|
||||
// Cut of the beginning of the input until the first '@'.
|
||||
$input = substr($input, strpos($input, '@'));
|
||||
|
||||
$this->_lexer->reset();
|
||||
$this->_lexer->setInput(trim($input, '* /'));
|
||||
$this->_lexer->moveNext();
|
||||
|
||||
if ($this->_lexer->isNextToken(Lexer::T_AT)) {
|
||||
return $this->Annotations();
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to match the given token with the current lookahead token.
|
||||
* If they match, updates the lookahead token; otherwise raises a syntax error.
|
||||
*
|
||||
* @param int|string token type or value
|
||||
* @return bool True if tokens match; false otherwise.
|
||||
*/
|
||||
public function match($token)
|
||||
{
|
||||
if ( ! ($this->_lexer->lookahead['type'] === $token)) {
|
||||
$this->syntaxError($this->_lexer->getLiteral($token));
|
||||
}
|
||||
$this->_lexer->moveNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new syntax error.
|
||||
*
|
||||
* @param string $expected Expected string.
|
||||
* @param array $token Optional token.
|
||||
* @throws AnnotationException
|
||||
*/
|
||||
private function syntaxError($expected, $token = null)
|
||||
{
|
||||
if ($token === null) {
|
||||
$token = $this->_lexer->lookahead;
|
||||
}
|
||||
|
||||
$message = "Expected {$expected}, got ";
|
||||
|
||||
if ($this->_lexer->lookahead === null) {
|
||||
$message .= 'end of string';
|
||||
} else {
|
||||
$message .= "'{$token['value']}' at position {$token['position']}";
|
||||
}
|
||||
|
||||
if (strlen($this->_context)) {
|
||||
$message .= ' in ' . $this->_context;
|
||||
}
|
||||
|
||||
$message .= '.';
|
||||
|
||||
throw AnnotationException::syntaxError($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotations ::= Annotation {[ "*" ]* [Annotation]}*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Annotations()
|
||||
{
|
||||
$this->_isNestedAnnotation = false;
|
||||
|
||||
$annotations = array();
|
||||
$annot = $this->Annotation();
|
||||
|
||||
if ($annot !== false) {
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
|
||||
while ($this->_lexer->lookahead !== null && $this->_lexer->isNextToken(Lexer::T_AT)) {
|
||||
$this->_isNestedAnnotation = false;
|
||||
|
||||
$annot = $this->Annotation();
|
||||
|
||||
if ($annot !== false) {
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotation ::= "@" AnnotationName ["(" [Values] ")"]
|
||||
* AnnotationName ::= QualifiedName | SimpleName | AliasedName
|
||||
* QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName
|
||||
* AliasedName ::= Alias ":" SimpleName
|
||||
* NameSpacePart ::= identifier
|
||||
* SimpleName ::= identifier
|
||||
* Alias ::= identifier
|
||||
*
|
||||
* @return mixed False if it is not a valid Annotation; instance of Annotation subclass otherwise.
|
||||
*/
|
||||
public function Annotation()
|
||||
{
|
||||
$values = array();
|
||||
$nameParts = array();
|
||||
|
||||
$this->match(Lexer::T_AT);
|
||||
$this->match(Lexer::T_IDENTIFIER);
|
||||
$nameParts[] = $this->_lexer->token['value'];
|
||||
|
||||
while ($this->_lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) {
|
||||
$this->match(Lexer::T_NAMESPACE_SEPARATOR);
|
||||
$this->match(Lexer::T_IDENTIFIER);
|
||||
$nameParts[] = $this->_lexer->token['value'];
|
||||
}
|
||||
|
||||
// Effectively pick the name of the class (append default NS if none, grab from NS alias, etc)
|
||||
if (count($nameParts) == 1) {
|
||||
if (strpos($nameParts[0], ':')) {
|
||||
list ($alias, $simpleName) = explode(':', $nameParts[0]);
|
||||
$name = $this->_namespaceAliases[$alias] . $simpleName;
|
||||
} else {
|
||||
$name = $this->_defaultAnnotationNamespace . $nameParts[0];
|
||||
}
|
||||
} else {
|
||||
$name = implode('\\', $nameParts);
|
||||
}
|
||||
|
||||
// Is it really an annotation class?
|
||||
if (
|
||||
( ! $this->_isNestedAnnotation && $this->_lexer->lookahead != null &&
|
||||
! $this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) &&
|
||||
! $this->_lexer->isNextToken(Lexer::T_AT)) ||
|
||||
! class_exists($name, false)
|
||||
) {
|
||||
$this->_lexer->skipUntil(Lexer::T_AT);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Next will be nested
|
||||
$this->_isNestedAnnotation = true;
|
||||
|
||||
if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
|
||||
$this->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
if ( ! $this->_lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) {
|
||||
$values = $this->Values();
|
||||
}
|
||||
|
||||
$this->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
return new $name($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Values ::= Array | Value {"," Value}*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Values()
|
||||
{
|
||||
$values = array();
|
||||
|
||||
// Handle the case of a single array as value, i.e. @Foo({....})
|
||||
if ($this->_lexer->isNextToken(Lexer::T_OPEN_CURLY_BRACES)) {
|
||||
$values['value'] = $this->Value();
|
||||
return $values;
|
||||
}
|
||||
|
||||
$values[] = $this->Value();
|
||||
|
||||
while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
|
||||
$this->match(Lexer::T_COMMA);
|
||||
$value = $this->Value();
|
||||
|
||||
if ( ! is_array($value)) {
|
||||
$this->syntaxError('Value', $value);
|
||||
}
|
||||
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
foreach ($values as $k => $value) {
|
||||
if (is_array($value) && is_string(key($value))) {
|
||||
$key = key($value);
|
||||
$values[$key] = $value[$key];
|
||||
} else {
|
||||
$values['value'] = $value;
|
||||
}
|
||||
|
||||
unset($values[$k]);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value ::= PlainValue | FieldAssignment
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Value()
|
||||
{
|
||||
$peek = $this->_lexer->glimpse();
|
||||
|
||||
if ($peek['value'] === '=') {
|
||||
return $this->FieldAssignment();
|
||||
}
|
||||
|
||||
return $this->PlainValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* PlainValue ::= integer | string | float | boolean | Array | Annotation
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function PlainValue()
|
||||
{
|
||||
if ($this->_lexer->isNextToken(Lexer::T_OPEN_CURLY_BRACES)) {
|
||||
return $this->Arrayx();
|
||||
}
|
||||
|
||||
if ($this->_lexer->isNextToken(Lexer::T_AT)) {
|
||||
return $this->Annotation();
|
||||
}
|
||||
|
||||
switch ($this->_lexer->lookahead['type']) {
|
||||
case Lexer::T_STRING:
|
||||
$this->match(Lexer::T_STRING);
|
||||
return $this->_lexer->token['value'];
|
||||
|
||||
case Lexer::T_INTEGER:
|
||||
$this->match(Lexer::T_INTEGER);
|
||||
return $this->_lexer->token['value'];
|
||||
|
||||
case Lexer::T_FLOAT:
|
||||
$this->match(Lexer::T_FLOAT);
|
||||
return $this->_lexer->token['value'];
|
||||
|
||||
case Lexer::T_TRUE:
|
||||
$this->match(Lexer::T_TRUE);
|
||||
return true;
|
||||
|
||||
case Lexer::T_FALSE:
|
||||
$this->match(Lexer::T_FALSE);
|
||||
return false;
|
||||
|
||||
default:
|
||||
$this->syntaxError('PlainValue');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FieldAssignment ::= FieldName "=" PlainValue
|
||||
* FieldName ::= identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function FieldAssignment()
|
||||
{
|
||||
$this->match(Lexer::T_IDENTIFIER);
|
||||
$fieldName = $this->_lexer->token['value'];
|
||||
$this->match(Lexer::T_EQUALS);
|
||||
|
||||
return array($fieldName => $this->PlainValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Array ::= "{" ArrayEntry {"," ArrayEntry}* "}"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Arrayx()
|
||||
{
|
||||
$array = $values = array();
|
||||
|
||||
$this->match(Lexer::T_OPEN_CURLY_BRACES);
|
||||
$values[] = $this->ArrayEntry();
|
||||
|
||||
while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
|
||||
$this->match(Lexer::T_COMMA);
|
||||
$values[] = $this->ArrayEntry();
|
||||
}
|
||||
|
||||
$this->match(Lexer::T_CLOSE_CURLY_BRACES);
|
||||
|
||||
foreach ($values as $value) {
|
||||
list ($key, $val) = $value;
|
||||
|
||||
if ($key !== null) {
|
||||
$array[$key] = $val;
|
||||
} else {
|
||||
$array[] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayEntry ::= Value | KeyValuePair
|
||||
* KeyValuePair ::= Key "=" PlainValue
|
||||
* Key ::= string | integer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ArrayEntry()
|
||||
{
|
||||
$peek = $this->_lexer->glimpse();
|
||||
|
||||
if ($peek['value'] == '=') {
|
||||
$this->match(
|
||||
$this->_lexer->isNextToken(Lexer::T_INTEGER) ? Lexer::T_INTEGER : Lexer::T_STRING
|
||||
);
|
||||
|
||||
$key = $this->_lexer->token['value'];
|
||||
$this->match(Lexer::T_EQUALS);
|
||||
|
||||
return array($key, $this->PlainValue());
|
||||
}
|
||||
|
||||
return array(null, $this->Value());
|
||||
}
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common\Cache;
|
||||
|
||||
/**
|
||||
* Base class for cache driver implementations.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
abstract class AbstractCache implements Cache
|
||||
{
|
||||
/** @var string The cache id to store the index of cache ids under */
|
||||
private $_cacheIdsIndexId = 'doctrine_cache_ids';
|
||||
|
||||
/** @var string The namespace to prefix all cache ids with */
|
||||
private $_namespace = null;
|
||||
|
||||
/**
|
||||
* Set the namespace to prefix all cache ids with.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return void
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->_namespace = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($id)
|
||||
{
|
||||
return $this->_doFetch($this->_getNamespacedId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function contains($id)
|
||||
{
|
||||
return $this->_doContains($this->_getNamespacedId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save($id, $data, $lifeTime = 0)
|
||||
{
|
||||
$id = $this->_getNamespacedId($id);
|
||||
return $this->_doSave($id, $data, $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$id = $this->_getNamespacedId($id);
|
||||
|
||||
if (strpos($id, '*') !== false) {
|
||||
return $this->deleteByRegex('/' . str_replace('*', '.*', $id) . '/');
|
||||
}
|
||||
|
||||
return $this->_doDelete($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
* @return array $deleted Array of the deleted cache ids
|
||||
*/
|
||||
public function deleteAll()
|
||||
{
|
||||
$ids = $this->getIds();
|
||||
foreach ($ids as $id) {
|
||||
$this->delete($id);
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache entries where the id matches a PHP regular expressions
|
||||
*
|
||||
* @param string $regex
|
||||
* @return array $deleted Array of the deleted cache ids
|
||||
*/
|
||||
public function deleteByRegex($regex)
|
||||
{
|
||||
$deleted = array();
|
||||
$ids = $this->getIds();
|
||||
foreach ($ids as $id) {
|
||||
if (preg_match($regex, $id)) {
|
||||
$this->delete($id);
|
||||
$deleted[] = $id;
|
||||
}
|
||||
}
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache entries where the id has the passed prefix
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return array $deleted Array of the deleted cache ids
|
||||
*/
|
||||
public function deleteByPrefix($prefix)
|
||||
{
|
||||
$deleted = array();
|
||||
$ids = $this->getIds();
|
||||
foreach ($ids as $id) {
|
||||
if (strpos($id, $prefix) === 0) {
|
||||
$this->delete($id);
|
||||
$deleted[] = $id;
|
||||
}
|
||||
}
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache entries where the id has the passed suffix
|
||||
*
|
||||
* @param string $suffix
|
||||
* @return array $deleted Array of the deleted cache ids
|
||||
*/
|
||||
public function deleteBySuffix($suffix)
|
||||
{
|
||||
$deleted = array();
|
||||
$ids = $this->getIds();
|
||||
foreach ($ids as $id) {
|
||||
if (substr($id, -1 * strlen($suffix)) === $suffix) {
|
||||
$this->delete($id);
|
||||
$deleted[] = $id;
|
||||
}
|
||||
}
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix the passed id with the configured namespace value
|
||||
*
|
||||
* @param string $id The id to namespace
|
||||
* @return string $id The namespaced id
|
||||
*/
|
||||
private function _getNamespacedId($id)
|
||||
{
|
||||
if ( ! $this->_namespace || strpos($id, $this->_namespace) === 0) {
|
||||
return $id;
|
||||
} else {
|
||||
return $this->_namespace . $id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches an entry from the cache.
|
||||
*
|
||||
* @param string $id cache id The id of the cache entry to fetch.
|
||||
* @return string The cached data or FALSE, if no cache entry exists for the given id.
|
||||
*/
|
||||
abstract protected function _doFetch($id);
|
||||
|
||||
/**
|
||||
* Test if an entry exists in the cache.
|
||||
*
|
||||
* @param string $id cache id The cache id of the entry to check for.
|
||||
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
|
||||
*/
|
||||
abstract protected function _doContains($id);
|
||||
|
||||
/**
|
||||
* Puts data into the cache.
|
||||
*
|
||||
* @param string $id The cache id.
|
||||
* @param string $data The cache entry/data.
|
||||
* @param int $lifeTime The lifetime. If != false, sets a specific lifetime for this cache entry (null => infinite lifeTime).
|
||||
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
|
||||
*/
|
||||
abstract protected function _doSave($id, $data, $lifeTime = false);
|
||||
|
||||
/**
|
||||
* Deletes a cache entry.
|
||||
*
|
||||
* @param string $id cache id
|
||||
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
|
||||
*/
|
||||
abstract protected function _doDelete($id);
|
||||
|
||||
/**
|
||||
* Get an array of all the cache ids stored
|
||||
*
|
||||
* @return array $ids
|
||||
*/
|
||||
abstract public function getIds();
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
<?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\Common\Cache;
|
||||
|
||||
/**
|
||||
* APC cache driver.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @todo Rename: APCCache
|
||||
*/
|
||||
class ApcCache extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds()
|
||||
{
|
||||
$ci = apc_cache_info('user');
|
||||
$keys = array();
|
||||
|
||||
foreach ($ci['cache_list'] as $entry) {
|
||||
$keys[] = $entry['info'];
|
||||
}
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doFetch($id)
|
||||
{
|
||||
return apc_fetch($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doContains($id)
|
||||
{
|
||||
$found = false;
|
||||
apc_fetch($id, $found);
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
return (bool) apc_store($id, $data, (int) $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doDelete($id)
|
||||
{
|
||||
return apc_delete($id);
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?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\Common\Cache;
|
||||
|
||||
/**
|
||||
* Array cache driver.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 3938 $
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
*/
|
||||
class ArrayCache extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* @var array $data
|
||||
*/
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds()
|
||||
{
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doFetch($id)
|
||||
{
|
||||
if (isset($this->data[$id])) {
|
||||
return $this->data[$id];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doContains($id)
|
||||
{
|
||||
return isset($this->data[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
$this->data[$id] = $data;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doDelete($id)
|
||||
{
|
||||
unset($this->data[$id]);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
<?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\Common\Cache;
|
||||
|
||||
/**
|
||||
* Interface for cache drivers.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 3938 $
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
interface Cache
|
||||
{
|
||||
/**
|
||||
* Fetches an entry from the cache.
|
||||
*
|
||||
* @param string $id cache id The id of the cache entry to fetch.
|
||||
* @return string The cached data or FALSE, if no cache entry exists for the given id.
|
||||
*/
|
||||
function fetch($id);
|
||||
|
||||
/**
|
||||
* Test if an entry exists in the cache.
|
||||
*
|
||||
* @param string $id cache id The cache id of the entry to check for.
|
||||
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
|
||||
*/
|
||||
function contains($id);
|
||||
|
||||
/**
|
||||
* Puts data into the cache.
|
||||
*
|
||||
* @param string $id The cache id.
|
||||
* @param string $data The cache entry/data.
|
||||
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime).
|
||||
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
|
||||
*/
|
||||
function save($id, $data, $lifeTime = 0);
|
||||
|
||||
/**
|
||||
* Deletes a cache entry.
|
||||
*
|
||||
* @param string $id cache id
|
||||
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
|
||||
*/
|
||||
function delete($id);
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
<?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\Common\Cache;
|
||||
|
||||
use \Memcache;
|
||||
|
||||
/**
|
||||
* Memcache cache driver.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 3938 $
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
*/
|
||||
class MemcacheCache extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* @var Memcache
|
||||
*/
|
||||
private $_memcache;
|
||||
|
||||
/**
|
||||
* Sets the memcache instance to use.
|
||||
*
|
||||
* @param Memcache $memcache
|
||||
*/
|
||||
public function setMemcache(Memcache $memcache)
|
||||
{
|
||||
$this->_memcache = $memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the memcache instance used by the cache.
|
||||
*
|
||||
* @return Memcache
|
||||
*/
|
||||
public function getMemcache()
|
||||
{
|
||||
return $this->_memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds()
|
||||
{
|
||||
$keys = array();
|
||||
$allSlabs = $this->_memcache->getExtendedStats('slabs');
|
||||
|
||||
foreach ($allSlabs as $server => $slabs) {
|
||||
if (is_array($slabs)) {
|
||||
foreach (array_keys($slabs) as $slabId) {
|
||||
$dump = $this->_memcache->getExtendedStats('cachedump', (int) $slabId);
|
||||
|
||||
if ($dump) {
|
||||
foreach ($dump as $entries) {
|
||||
if ($entries) {
|
||||
$keys = array_merge($keys, array_keys($entries));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doFetch($id)
|
||||
{
|
||||
return $this->_memcache->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doContains($id)
|
||||
{
|
||||
return (bool) $this->_memcache->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
return $this->_memcache->set($id, $data, 0, (int) $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doDelete($id)
|
||||
{
|
||||
return $this->_memcache->delete($id);
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?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\Common\Cache;
|
||||
|
||||
/**
|
||||
* Xcache cache driver.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 3938 $
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
*/
|
||||
class XcacheCache extends AbstractCache
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds()
|
||||
{
|
||||
$this->_checkAuth();
|
||||
$keys = array();
|
||||
for ($i = 0, $count = xcache_count(XC_TYPE_VAR); $i < $count; $i++) {
|
||||
$entries = xcache_list(XC_TYPE_VAR, $i);
|
||||
if (is_array($entries['cache_list'])) {
|
||||
foreach ($entries['cache_list'] as $entry) {
|
||||
$keys[] = $entry['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doFetch($id)
|
||||
{
|
||||
return $this->_doContains($id) ? unserialize( xcache_get($id) ) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doContains($id)
|
||||
{
|
||||
return xcache_isset($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
return xcache_set($id, serialize($data), (int) $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _doDelete($id)
|
||||
{
|
||||
return xcache_unset($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that xcache.admin.enable_auth is Off
|
||||
*
|
||||
* @throws \BadMethodCallException When xcache.admin.enable_auth is On
|
||||
* @return void
|
||||
*/
|
||||
protected function _checkAuth()
|
||||
{
|
||||
if (ini_get('xcache.admin.enable_auth')) {
|
||||
throw new \BadMethodCallException('To use all features of \Doctrine\Common\Cache\XcacheCache, you must set "xcache.admin.enable_auth" to "Off" in your php.ini.');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common;
|
||||
|
||||
/**
|
||||
* A <tt>ClassLoader</tt> is an autoloader for class files that can be
|
||||
* installed on the SPL autoload stack. It is a class loader that loads only classes
|
||||
* of a specific namespace or all namespaces and is suitable for working together
|
||||
* with other autoloaders in the SPL autoload stack.
|
||||
*
|
||||
* If no include path is configured through {@link setIncludePath}, a ClassLoader
|
||||
* relies on the PHP include_path.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
private $_fileExtension = '.php';
|
||||
private $_namespace;
|
||||
private $_includePath;
|
||||
private $_namespaceSeparator = '\\';
|
||||
|
||||
/**
|
||||
* Creates a new <tt>ClassLoader</tt> that loads classes of the
|
||||
* specified namespace.
|
||||
*
|
||||
* @param string $ns The namespace to use.
|
||||
*/
|
||||
public function __construct($ns = null, $includePath = null)
|
||||
{
|
||||
$this->_namespace = $ns;
|
||||
$this->_includePath = $includePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the namespace separator used by classes in the namespace of this class loader.
|
||||
*
|
||||
* @param string $sep The separator to use.
|
||||
*/
|
||||
public function setNamespaceSeparator($sep)
|
||||
{
|
||||
$this->_namespaceSeparator = $sep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the namespace separator used by classes in the namespace of this class loader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespaceSeparator()
|
||||
{
|
||||
return $this->_namespaceSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base include path for all class files in the namespace of this class loader.
|
||||
*
|
||||
* @param string $includePath
|
||||
*/
|
||||
public function setIncludePath($includePath)
|
||||
{
|
||||
$this->_includePath = $includePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base include path for all class files in the namespace of this class loader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIncludePath()
|
||||
{
|
||||
return $this->_includePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file extension of class files in the namespace of this class loader.
|
||||
*
|
||||
* @param string $fileExtension
|
||||
*/
|
||||
public function setFileExtension($fileExtension)
|
||||
{
|
||||
$this->_fileExtension = $fileExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file extension of class files in the namespace of this class loader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
return $this->_fileExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs this class loader on the SPL autoload stack.
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls this class loader on the SPL autoload stack.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $classname The name of the class to load.
|
||||
* @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
|
||||
*/
|
||||
public function loadClass($className)
|
||||
{
|
||||
if ($this->_namespace !== null && strpos($className, $this->_namespace.$this->_namespaceSeparator) !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '')
|
||||
. str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $className)
|
||||
. $this->_fileExtension;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common\Collections;
|
||||
|
||||
use Closure, ArrayIterator;
|
||||
|
||||
/**
|
||||
* An ArrayCollection is a Collection implementation that wraps a regular PHP array.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ArrayCollection implements Collection
|
||||
{
|
||||
/**
|
||||
* An array containing the entries of this collection.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_elements;
|
||||
|
||||
/**
|
||||
* Initializes a new ArrayCollection.
|
||||
*
|
||||
* @param array $elements
|
||||
*/
|
||||
public function __construct(array $elements = array())
|
||||
{
|
||||
$this->_elements = $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PHP array representation of this collection.
|
||||
*
|
||||
* @return array The PHP array representation of this collection.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal iterator to the first element in the collection and
|
||||
* returns this element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return reset($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal iterator to the last element in the collection and
|
||||
* returns this element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return end($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current key/index at the current internal iterator position.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the internal iterator position to the next element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
next($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the element of the collection at the current internal iterator position.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an element with a specific key/index from the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed The removed element or NULL, if no element exists for the given key.
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
if (isset($this->_elements[$key])) {
|
||||
$removed = $this->_elements[$key];
|
||||
unset($this->_elements[$key]);
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified element from the collection, if it is found.
|
||||
*
|
||||
* @param mixed $element
|
||||
* @return boolean
|
||||
*/
|
||||
public function removeElement($element)
|
||||
{
|
||||
$key = array_search($element, $this->_elements, true);
|
||||
|
||||
if ($key !== false) {
|
||||
$removed = $this->_elements[$key];
|
||||
unset($this->_elements[$key]);
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayAccess implementation of offsetExists()
|
||||
*
|
||||
* @see containsKey()
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->containsKey($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayAccess implementation of offsetGet()
|
||||
*
|
||||
* @see get()
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayAccess implementation of offsetGet()
|
||||
*
|
||||
* @see add()
|
||||
* @see set()
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if ( ! isset($offset)) {
|
||||
return $this->add($value);
|
||||
}
|
||||
return $this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayAccess implementation of offsetUnset()
|
||||
*
|
||||
* @see remove()
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
return $this->remove($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the collection contains a specific key/index.
|
||||
*
|
||||
* @param mixed $key The key to check for.
|
||||
* @return boolean TRUE if the given key/index exists, FALSE otherwise.
|
||||
*/
|
||||
public function containsKey($key)
|
||||
{
|
||||
return isset($this->_elements[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given element is contained in the collection.
|
||||
* Only element values are compared, not keys. The comparison of two elements
|
||||
* is strict, that means not only the value but also the type must match.
|
||||
* For objects this means reference equality.
|
||||
*
|
||||
* @param mixed $element
|
||||
* @return boolean TRUE if the given element is contained in the collection,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
public function contains($element)
|
||||
{
|
||||
return in_array($element, $this->_elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the existance of an element that satisfies the given predicate.
|
||||
*
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
|
||||
*/
|
||||
public function exists(Closure $p)
|
||||
{
|
||||
foreach ($this->_elements as $key => $element)
|
||||
if ($p($key, $element)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a given element and, if found, returns the corresponding key/index
|
||||
* of that element. The comparison of two elements is strict, that means not
|
||||
* only the value but also the type must match.
|
||||
* For objects this means reference equality.
|
||||
*
|
||||
* @param mixed $element The element to search for.
|
||||
* @return mixed The key/index of the element or FALSE if the element was not found.
|
||||
*/
|
||||
public function indexOf($element)
|
||||
{
|
||||
return array_search($element, $this->_elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the element with the given key/index.
|
||||
*
|
||||
* @param mixed $key The key.
|
||||
* @return mixed The element or NULL, if no element exists for the given key.
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (isset($this->_elements[$key])) {
|
||||
return $this->_elements[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all keys/indexes of the collection elements.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys()
|
||||
{
|
||||
return array_keys($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all elements.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return array_values($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the collection.
|
||||
*
|
||||
* Implementation of the Countable interface.
|
||||
*
|
||||
* @return integer The number of elements in the collection.
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds/sets an element in the collection at the index / with the specified key.
|
||||
*
|
||||
* When the collection is a Map this is like put(key,value)/add(key,value).
|
||||
* When the collection is a List this is like add(position,value).
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->_elements[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the collection.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean Always TRUE.
|
||||
*/
|
||||
public function add($value)
|
||||
{
|
||||
$this->_elements[] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the collection is empty.
|
||||
*
|
||||
* Note: This is preferrable over count() == 0.
|
||||
*
|
||||
* @return boolean TRUE if the collection is empty, FALSE otherwise.
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return ! $this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an iterator for iterating over the elements in the collection.
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function to each element in the collection and returns
|
||||
* a new collection with the elements returned by the function.
|
||||
*
|
||||
* @param Closure $func
|
||||
* @return Collection
|
||||
*/
|
||||
public function map(Closure $func)
|
||||
{
|
||||
return new ArrayCollection(array_map($func, $this->_elements));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the elements of this collection that satisfy the predicate p.
|
||||
* The order of the elements is preserved.
|
||||
*
|
||||
* @param Closure $p The predicate used for filtering.
|
||||
* @return Collection A collection with the results of the filter operation.
|
||||
*/
|
||||
public function filter(Closure $p)
|
||||
{
|
||||
return new ArrayCollection(array_filter($this->_elements, $p));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given predicate p to all elements of this collection,
|
||||
* returning true, if the predicate yields true for all elements.
|
||||
*
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
|
||||
*/
|
||||
public function forAll(Closure $p)
|
||||
{
|
||||
foreach ($this->_elements as $key => $element) {
|
||||
if ( ! $p($key, $element)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partitions this collection in two collections according to a predicate.
|
||||
* Keys are preserved in the resulting collections.
|
||||
*
|
||||
* @param Closure $p The predicate on which to partition.
|
||||
* @return array An array with two elements. The first element contains the collection
|
||||
* of elements where the predicate returned TRUE, the second element
|
||||
* contains the collection of elements where the predicate returned FALSE.
|
||||
*/
|
||||
public function partition(Closure $p)
|
||||
{
|
||||
$coll1 = $coll2 = array();
|
||||
foreach ($this->_elements as $key => $element) {
|
||||
if ($p($key, $element)) {
|
||||
$coll1[$key] = $element;
|
||||
} else {
|
||||
$coll2[$key] = $element;
|
||||
}
|
||||
}
|
||||
return array(new ArrayCollection($coll1), new ArrayCollection($coll2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the collection.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->_elements = array();
|
||||
}
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common\Collections;
|
||||
|
||||
use Closure, Countable, IteratorAggregate, ArrayAccess;
|
||||
|
||||
/**
|
||||
* The missing (SPL) Collection/Array/OrderedMap interface.
|
||||
*
|
||||
* A Collection resembles the nature of a regular PHP array. That is,
|
||||
* it is essentially an <b>ordered map</b> that can also be used
|
||||
* like a list.
|
||||
*
|
||||
* A Collection has an internal iterator just like a PHP array. In addition,
|
||||
* a Collection can be iterated with external iterators, which is preferrable.
|
||||
* To use an external iterator simply use the foreach language construct to
|
||||
* iterate over the collection (which calls {@link getIterator()} internally) or
|
||||
* explicitly retrieve an iterator though {@link getIterator()} which can then be
|
||||
* used to iterate over the collection.
|
||||
* You can not rely on the internal iterator of the collection being at a certain
|
||||
* position unless you explicitly positioned it before. Prefer iteration with
|
||||
* external iterators.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
interface Collection extends Countable, IteratorAggregate, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Adds an element at the end of the collection.
|
||||
*
|
||||
* @param mixed $element The element to add.
|
||||
* @return boolean Always TRUE.
|
||||
*/
|
||||
function add($element);
|
||||
|
||||
/**
|
||||
* Clears the collection, removing all elements.
|
||||
*/
|
||||
function clear();
|
||||
|
||||
/**
|
||||
* Checks whether an element is contained in the collection.
|
||||
* This is an O(n) operation, where n is the size of the collection.
|
||||
*
|
||||
* @param mixed $element The element to search for.
|
||||
* @return boolean TRUE if the collection contains the element, FALSE otherwise.
|
||||
*/
|
||||
function contains($element);
|
||||
|
||||
/**
|
||||
* Checks whether the collection is empty (contains no elements).
|
||||
*
|
||||
* @return boolean TRUE if the collection is empty, FALSE otherwise.
|
||||
*/
|
||||
function isEmpty();
|
||||
|
||||
/**
|
||||
* Removes the element at the specified index from the collection.
|
||||
*
|
||||
* @param string|integer $key The kex/index of the element to remove.
|
||||
* @return mixed The removed element or NULL, if the collection did not contain the element.
|
||||
*/
|
||||
function remove($key);
|
||||
|
||||
/**
|
||||
* Removes an element from the collection.
|
||||
*
|
||||
* @param mixed $element The element to remove.
|
||||
* @return mixed The removed element or NULL, if the collection did not contain the element.
|
||||
*/
|
||||
function removeElement($element);
|
||||
|
||||
/**
|
||||
* Checks whether the collection contains an element with the specified key/index.
|
||||
*
|
||||
* @param string|integer $key The key/index to check for.
|
||||
* @return boolean TRUE if the collection contains an element with the specified key/index,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
function containsKey($key);
|
||||
|
||||
/**
|
||||
* Gets the element at the specified key/index.
|
||||
*
|
||||
* @param string|integer $key The key/index of the element to retrieve.
|
||||
* @return mixed
|
||||
*/
|
||||
function get($key);
|
||||
|
||||
/**
|
||||
* Gets all keys/indices of the collection.
|
||||
*
|
||||
* @return array The keys/indices of the collection, in the order of the corresponding
|
||||
* elements in the collection.
|
||||
*/
|
||||
function getKeys();
|
||||
|
||||
/**
|
||||
* Gets all values of the collection.
|
||||
*
|
||||
* @return array The values of all elements in the collection, in the order they
|
||||
* appear in the collection.
|
||||
*/
|
||||
function getValues();
|
||||
|
||||
/**
|
||||
* Sets an element in the collection at the specified key/index.
|
||||
*
|
||||
* @param string|integer $key The key/index of the element to set.
|
||||
* @param mixed $value The element to set.
|
||||
*/
|
||||
function set($key, $value);
|
||||
|
||||
/**
|
||||
* Gets a native PHP array representation of the collection.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function toArray();
|
||||
|
||||
/**
|
||||
* Sets the internal iterator to the first element in the collection and
|
||||
* returns this element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function first();
|
||||
|
||||
/**
|
||||
* Sets the internal iterator to the last element in the collection and
|
||||
* returns this element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function last();
|
||||
|
||||
/**
|
||||
* Gets the key/index of the element at the current iterator position.
|
||||
*
|
||||
*/
|
||||
function key();
|
||||
|
||||
/**
|
||||
* Gets the element of the collection at the current iterator position.
|
||||
*
|
||||
*/
|
||||
function current();
|
||||
|
||||
/**
|
||||
* Moves the internal iterator position to the next element.
|
||||
*
|
||||
*/
|
||||
function next();
|
||||
|
||||
/**
|
||||
* Tests for the existence of an element that satisfies the given predicate.
|
||||
*
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
|
||||
*/
|
||||
function exists(Closure $p);
|
||||
|
||||
/**
|
||||
* Returns all the elements of this collection that satisfy the predicate p.
|
||||
* The order of the elements is preserved.
|
||||
*
|
||||
* @param Closure $p The predicate used for filtering.
|
||||
* @return Collection A collection with the results of the filter operation.
|
||||
*/
|
||||
function filter(Closure $p);
|
||||
|
||||
/**
|
||||
* Applies the given predicate p to all elements of this collection,
|
||||
* returning true, if the predicate yields true for all elements.
|
||||
*
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
|
||||
*/
|
||||
function forAll(Closure $p);
|
||||
|
||||
/**
|
||||
* Applies the given function to each element in the collection and returns
|
||||
* a new collection with the elements returned by the function.
|
||||
*
|
||||
* @param Closure $func
|
||||
* @return Collection
|
||||
*/
|
||||
function map(Closure $func);
|
||||
|
||||
/**
|
||||
* Partitions this collection in two collections according to a predicate.
|
||||
* Keys are preserved in the resulting collections.
|
||||
*
|
||||
* @param Closure $p The predicate on which to partition.
|
||||
* @return array An array with two elements. The first element contains the collection
|
||||
* of elements where the predicate returned TRUE, the second element
|
||||
* contains the collection of elements where the predicate returned FALSE.
|
||||
*/
|
||||
function partition(Closure $p);
|
||||
|
||||
/**
|
||||
* Gets the index/key of a given element. The comparison of two elements is strict,
|
||||
* that means not only the value but also the type must match.
|
||||
* For objects this means reference equality.
|
||||
*
|
||||
* @param mixed $element The element to search for.
|
||||
* @return mixed The key/index of the element or FALSE if the element was not found.
|
||||
*/
|
||||
function indexOf($element);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common;
|
||||
|
||||
/**
|
||||
* Base exception class for package Doctrine\Common
|
||||
* @author heinrich
|
||||
*
|
||||
*/
|
||||
class CommonException extends \Exception {
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
<?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\Common;
|
||||
|
||||
/**
|
||||
* EventArgs is the base class for classes containing event data.
|
||||
*
|
||||
* This class contains no event data. It is used by events that do not pass state
|
||||
* information to an event handler when an event is raised. The single empty EventArgs
|
||||
* instance can be obtained through {@link getEmptyInstance}.
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
class EventArgs
|
||||
{
|
||||
/**
|
||||
* @var EventArgs Single instance of EventArgs
|
||||
* @static
|
||||
*/
|
||||
private static $_emptyEventArgsInstance;
|
||||
|
||||
/**
|
||||
* Gets the single, empty and immutable EventArgs instance.
|
||||
*
|
||||
* This instance will be used when events are dispatched without any parameter,
|
||||
* like this: EventManager::dispatchEvent('eventname');
|
||||
*
|
||||
* The benefit from this is that only one empty instance is instantiated and shared
|
||||
* (otherwise there would be instances for every dispatched in the abovementioned form)
|
||||
*
|
||||
* @see EventManager::dispatchEvent
|
||||
* @link http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
|
||||
* @static
|
||||
* @return EventArgs
|
||||
*/
|
||||
public static function getEmptyInstance()
|
||||
{
|
||||
if ( ! self::$_emptyEventArgsInstance) {
|
||||
self::$_emptyEventArgsInstance = new EventArgs;
|
||||
}
|
||||
|
||||
return self::$_emptyEventArgsInstance;
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
<?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\Common;
|
||||
|
||||
use Doctrine\Common\Events\Event;
|
||||
|
||||
/**
|
||||
* The EventManager is the central point of Doctrine's event listener system.
|
||||
* Listeners are registered on the manager and events are dispatched through the
|
||||
* manager.
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
class EventManager
|
||||
{
|
||||
/**
|
||||
* Map of registered listeners.
|
||||
* <event> => <listeners>
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_listeners = array();
|
||||
|
||||
/**
|
||||
* Dispatches an event to all registered listeners.
|
||||
*
|
||||
* @param string $eventName The name of the event to dispatch. The name of the event is
|
||||
* the name of the method that is invoked on listeners.
|
||||
* @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
|
||||
* If not supplied, the single empty EventArgs instance is used.
|
||||
* @return boolean
|
||||
*/
|
||||
public function dispatchEvent($eventName, EventArgs $eventArgs = null)
|
||||
{
|
||||
if (isset($this->_listeners[$eventName])) {
|
||||
$eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs;
|
||||
|
||||
foreach ($this->_listeners[$eventName] as $listener) {
|
||||
$listener->$eventName($eventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the listeners of a specific event or all listeners.
|
||||
*
|
||||
* @param string $event The name of the event.
|
||||
* @return array The event listeners for the specified event, or all event listeners.
|
||||
*/
|
||||
public function getListeners($event = null)
|
||||
{
|
||||
return $event ? $this->_listeners[$event] : $this->_listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an event has any registered listeners.
|
||||
*
|
||||
* @param string $event
|
||||
* @return boolean TRUE if the specified event has any listeners, FALSE otherwise.
|
||||
*/
|
||||
public function hasListeners($event)
|
||||
{
|
||||
return isset($this->_listeners[$event]) && $this->_listeners[$event];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event listener that listens on the specified events.
|
||||
*
|
||||
* @param string|array $events The event(s) to listen on.
|
||||
* @param object $listener The listener object.
|
||||
*/
|
||||
public function addEventListener($events, $listener)
|
||||
{
|
||||
// Picks the hash code related to that listener
|
||||
$hash = spl_object_hash($listener);
|
||||
|
||||
foreach ((array) $events as $event) {
|
||||
// Overrides listener if a previous one was associated already
|
||||
// Prevents duplicate listeners on same event (same instance only)
|
||||
$this->_listeners[$event][$hash] = $listener;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event listener from the specified events.
|
||||
*
|
||||
* @param string|array $events
|
||||
* @param object $listener
|
||||
*/
|
||||
public function removeEventListener($events, $listener)
|
||||
{
|
||||
// Picks the hash code related to that listener
|
||||
$hash = spl_object_hash($listener);
|
||||
|
||||
foreach ((array) $events as $event) {
|
||||
// Check if actually have this listener associated
|
||||
if (isset($this->_listeners[$event][$hash])) {
|
||||
unset($this->_listeners[$event][$hash]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an EventSubscriber. The subscriber is asked for all the events he is
|
||||
* interested in and added as a listener for these events.
|
||||
*
|
||||
* @param Doctrine\Common\EventSubscriber $subscriber The subscriber.
|
||||
*/
|
||||
public function addEventSubscriber(EventSubscriber $subscriber)
|
||||
{
|
||||
$this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: EventListener.php 4653 2008-07-10 17:17:58Z romanb $
|
||||
*
|
||||
* 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\Common;
|
||||
|
||||
/**
|
||||
* An EventSubscriber knows himself what events he is interested in.
|
||||
* If an EventSubscriber is added to an EventManager, the manager invokes
|
||||
* {@link getSubscribedEvents} and registers the subscriber as a listener for all
|
||||
* returned events.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
interface EventSubscriber
|
||||
{
|
||||
/**
|
||||
* Returns an array of events this subscriber wants to listen to.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSubscribedEvents();
|
||||
}
|
@ -1,255 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Common;
|
||||
|
||||
/**
|
||||
* Base class for writing simple lexers, i.e. for creating small DSLs.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @todo Rename: AbstractLexer
|
||||
*/
|
||||
abstract class Lexer
|
||||
{
|
||||
/**
|
||||
* @var array Array of scanned tokens
|
||||
*/
|
||||
private $_tokens = array();
|
||||
|
||||
/**
|
||||
* @var integer Current lexer position in input string
|
||||
*/
|
||||
private $_position = 0;
|
||||
|
||||
/**
|
||||
* @var integer Current peek of current lexer position
|
||||
*/
|
||||
private $_peek = 0;
|
||||
|
||||
/**
|
||||
* @var array The next token in the input.
|
||||
*/
|
||||
public $lookahead;
|
||||
|
||||
/**
|
||||
* @var array The last matched/seen token.
|
||||
*/
|
||||
public $token;
|
||||
|
||||
/**
|
||||
* Sets the input data to be tokenized.
|
||||
*
|
||||
* The Lexer is immediately reset and the new input tokenized.
|
||||
* Any unprocessed tokens from any previous input are lost.
|
||||
*
|
||||
* @param string $input The input to be tokenized.
|
||||
*/
|
||||
public function setInput($input)
|
||||
{
|
||||
$this->_tokens = array();
|
||||
$this->reset();
|
||||
$this->_scan($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the lexer.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->lookahead = null;
|
||||
$this->token = null;
|
||||
$this->_peek = 0;
|
||||
$this->_position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the peek pointer to 0.
|
||||
*/
|
||||
public function resetPeek()
|
||||
{
|
||||
$this->_peek = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the lexer position on the input to the given position.
|
||||
*
|
||||
* @param integer $position Position to place the lexical scanner
|
||||
*/
|
||||
public function resetPosition($position = 0)
|
||||
{
|
||||
$this->_position = $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given token matches the current lookahead.
|
||||
*
|
||||
* @param integer|string $token
|
||||
* @return boolean
|
||||
*/
|
||||
public function isNextToken($token)
|
||||
{
|
||||
return $this->lookahead['type'] === $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves to the next token in the input string.
|
||||
*
|
||||
* A token is an associative array containing three items:
|
||||
* - 'value' : the string value of the token in the input string
|
||||
* - 'type' : the type of the token (identifier, numeric, string, input
|
||||
* parameter, none)
|
||||
* - 'position' : the position of the token in the input string
|
||||
*
|
||||
* @return array|null the next token; null if there is no more tokens left
|
||||
*/
|
||||
public function moveNext()
|
||||
{
|
||||
$this->_peek = 0;
|
||||
$this->token = $this->lookahead;
|
||||
$this->lookahead = (isset($this->_tokens[$this->_position]))
|
||||
? $this->_tokens[$this->_position++] : null;
|
||||
|
||||
return $this->lookahead !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the lexer to skip input tokens until it sees a token with the given value.
|
||||
*
|
||||
* @param $type The token type to skip until.
|
||||
*/
|
||||
public function skipUntil($type)
|
||||
{
|
||||
while ($this->lookahead !== null && $this->lookahead['type'] !== $type) {
|
||||
$this->moveNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given value is identical to the given token
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param integer $token
|
||||
* @return boolean
|
||||
*/
|
||||
public function isA($value, $token)
|
||||
{
|
||||
return $this->_getType($value) === $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the lookahead token forward.
|
||||
*
|
||||
* @return array | null The next token or NULL if there are no more tokens ahead.
|
||||
*/
|
||||
public function peek()
|
||||
{
|
||||
if (isset($this->_tokens[$this->_position + $this->_peek])) {
|
||||
return $this->_tokens[$this->_position + $this->_peek++];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the next token, returns it and immediately resets the peek.
|
||||
*
|
||||
* @return array|null The next token or NULL if there are no more tokens ahead.
|
||||
*/
|
||||
public function glimpse()
|
||||
{
|
||||
$peek = $this->peek();
|
||||
$this->_peek = 0;
|
||||
return $peek;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the input string for tokens.
|
||||
*
|
||||
* @param string $input a query string
|
||||
*/
|
||||
protected function _scan($input)
|
||||
{
|
||||
static $regex;
|
||||
|
||||
if ( ! isset($regex)) {
|
||||
$regex = '/(' . implode(')|(', $this->getCatchablePatterns()) . ')|'
|
||||
. implode('|', $this->getNonCatchablePatterns()) . '/i';
|
||||
}
|
||||
|
||||
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
|
||||
$matches = preg_split($regex, $input, -1, $flags);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
// Must remain before 'value' assignment since it can change content
|
||||
$type = $this->_getType($match[0]);
|
||||
|
||||
$this->_tokens[] = array(
|
||||
'value' => $match[0],
|
||||
'type' => $type,
|
||||
'position' => $match[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the literal for a given token.
|
||||
*
|
||||
* @param integer $token
|
||||
* @return string
|
||||
*/
|
||||
public function getLiteral($token)
|
||||
{
|
||||
$className = get_class($this);
|
||||
$reflClass = new \ReflectionClass($className);
|
||||
$constants = $reflClass->getConstants();
|
||||
|
||||
foreach ($constants as $name => $value) {
|
||||
if ($value === $token) {
|
||||
return $className . '::' . $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lexical catchable patterns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getCatchablePatterns();
|
||||
|
||||
/**
|
||||
* Lexical non-catchable patterns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getNonCatchablePatterns();
|
||||
|
||||
/**
|
||||
* Retrieve token type. Also processes the token value if necessary.
|
||||
*
|
||||
* @param string $value
|
||||
* @return integer
|
||||
*/
|
||||
abstract protected function _getType(&$value);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?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\Common;
|
||||
|
||||
/**
|
||||
* Contract for classes that provide the service of notifying listeners of
|
||||
* changes to their properties.
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
interface NotifyPropertyChanged
|
||||
{
|
||||
/**
|
||||
* Adds a listener that wants to be notified about property changes.
|
||||
*
|
||||
* @param PropertyChangedListener $listener
|
||||
*/
|
||||
function addPropertyChangedListener(PropertyChangedListener $listener);
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
<?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\Common;
|
||||
|
||||
/**
|
||||
* Contract for classes that are potential listeners of a <tt>NotifyPropertyChanged</tt>
|
||||
* implementor.
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
interface PropertyChangedListener
|
||||
{
|
||||
/**
|
||||
* Notifies the listener of a property change.
|
||||
*
|
||||
* @param object $sender The object on which the property changed.
|
||||
* @param string $propertyName The name of the property that changed.
|
||||
* @param mixed $oldValue The old value of the property that changed.
|
||||
* @param mixed $newValue The new value of the property that changed.
|
||||
*/
|
||||
function propertyChanged($sender, $propertyName, $oldValue, $newValue);
|
||||
}
|
||||
|
@ -1,131 +0,0 @@
|
||||
<?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\Common\Util;
|
||||
|
||||
/**
|
||||
* Static class containing most used debug methods.
|
||||
*
|
||||
* @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 Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
|
||||
*/
|
||||
final class Debug
|
||||
{
|
||||
/**
|
||||
* Private constructor (prevents from instantiation)
|
||||
*
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Prints a dump of the public, protected and private properties of $var.
|
||||
*
|
||||
* @static
|
||||
* @link http://xdebug.org/
|
||||
* @param mixed $var
|
||||
* @param integer $maxDepth Maximum nesting level for object properties
|
||||
*/
|
||||
public static function dump($var, $maxDepth = 2)
|
||||
{
|
||||
ini_set('html_errors', 'On');
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
ini_set('xdebug.var_display_max_depth', $maxDepth);
|
||||
}
|
||||
|
||||
$var = self::export($var, $maxDepth++);
|
||||
|
||||
ob_start();
|
||||
var_dump($var);
|
||||
$dump = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
echo strip_tags(html_entity_decode($dump));
|
||||
|
||||
ini_set('html_errors', 'Off');
|
||||
}
|
||||
|
||||
public static function export($var, $maxDepth)
|
||||
{
|
||||
$return = null;
|
||||
$isObj = is_object($var);
|
||||
|
||||
if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) {
|
||||
$var = $var->toArray();
|
||||
}
|
||||
|
||||
if ($maxDepth) {
|
||||
if (is_array($var)) {
|
||||
$return = array();
|
||||
|
||||
foreach ($var as $k => $v) {
|
||||
$return[$k] = self::export($v, $maxDepth - 1);
|
||||
}
|
||||
} else if ($isObj) {
|
||||
if ($var instanceof \DateTime) {
|
||||
$return = $var->format('c');
|
||||
} else {
|
||||
$reflClass = new \ReflectionClass(get_class($var));
|
||||
$return = new \stdclass();
|
||||
$return->{'__CLASS__'} = get_class($var);
|
||||
|
||||
if ($var instanceof \Doctrine\ORM\Proxy\Proxy && ! $var->__isInitialized__) {
|
||||
$reflProperty = $reflClass->getProperty('_identifier');
|
||||
$reflProperty->setAccessible(true);
|
||||
|
||||
foreach ($reflProperty->getValue($var) as $name => $value) {
|
||||
$return->$name = self::export($value, $maxDepth - 1);
|
||||
}
|
||||
} else {
|
||||
$excludeProperties = array();
|
||||
|
||||
if ($var instanceof \Doctrine\ORM\Proxy\Proxy) {
|
||||
$excludeProperties = array('_entityPersister', '__isInitialized__', '_identifier');
|
||||
}
|
||||
|
||||
foreach ($reflClass->getProperties() as $reflProperty) {
|
||||
$name = $reflProperty->getName();
|
||||
|
||||
if ( ! in_array($name, $excludeProperties)) {
|
||||
$reflProperty->setAccessible(true);
|
||||
|
||||
$return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$return = $var;
|
||||
}
|
||||
} else {
|
||||
$return = is_object($var) ? get_class($var)
|
||||
: (is_array($var) ? 'Array(' . count($var) . ')' : $var);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Inflector.php 3189 2007-11-18 20:37:44Z meus $
|
||||
*
|
||||
* 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\Common\Util;
|
||||
|
||||
/**
|
||||
* Doctrine inflector has static methods for inflecting text
|
||||
*
|
||||
* The methods in these classes are from several different sources collected
|
||||
* across several different php projects and several different authors. The
|
||||
* original author names and emails are not known
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 3189 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class Inflector
|
||||
{
|
||||
/**
|
||||
* Convert word in to the format for a Doctrine table name. Converts 'ModelName' to 'model_name'
|
||||
*
|
||||
* @param string $word Word to tableize
|
||||
* @return string $word Tableized word
|
||||
*/
|
||||
public static function tableize($word)
|
||||
{
|
||||
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName'
|
||||
*
|
||||
* @param string $word Word to classify
|
||||
* @return string $word Classified word
|
||||
*/
|
||||
public static function classify($word)
|
||||
{
|
||||
return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Camelize a word. This uses the classify() method and turns the first character to lowercase
|
||||
*
|
||||
* @param string $word
|
||||
* @return string $word
|
||||
*/
|
||||
public static function camelize($word)
|
||||
{
|
||||
return lcfirst(self::classify($word));
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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;
|
||||
|
||||
use Doctrine\DBAL\Logging\SQLLogger;
|
||||
|
||||
/**
|
||||
* Configuration container for the Doctrine DBAL.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @internal When adding a new configuration option just write a getter/setter
|
||||
* pair and add the option to the _attributes array with a proper default value.
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* The attributes that are contained in the configuration.
|
||||
* Values are default values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_attributes = array();
|
||||
|
||||
/**
|
||||
* Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
|
||||
*
|
||||
* @param SQLLogger $logger
|
||||
*/
|
||||
public function setSQLLogger(SQLLogger $logger)
|
||||
{
|
||||
$this->_attributes['sqlLogger'] = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL logger that is used.
|
||||
*
|
||||
* @return SQLLogger
|
||||
*/
|
||||
public function getSQLLogger()
|
||||
{
|
||||
return isset($this->_attributes['sqlLogger']) ?
|
||||
$this->_attributes['sqlLogger'] : null;
|
||||
}
|
||||
}
|
@ -1,935 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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;
|
||||
|
||||
use PDO, Closure, Exception,
|
||||
Doctrine\DBAL\Types\Type,
|
||||
Doctrine\DBAL\Driver\Connection as DriverConnection,
|
||||
Doctrine\Common\EventManager,
|
||||
Doctrine\DBAL\DBALException;
|
||||
|
||||
/**
|
||||
* A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like
|
||||
* events, transaction isolation levels, configuration, emulated transaction nesting,
|
||||
* lazy connecting and more.
|
||||
*
|
||||
* @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 Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (MDB2 library)
|
||||
*/
|
||||
class Connection implements DriverConnection
|
||||
{
|
||||
/**
|
||||
* Constant for transaction isolation level READ UNCOMMITTED.
|
||||
*/
|
||||
const TRANSACTION_READ_UNCOMMITTED = 1;
|
||||
|
||||
/**
|
||||
* Constant for transaction isolation level READ COMMITTED.
|
||||
*/
|
||||
const TRANSACTION_READ_COMMITTED = 2;
|
||||
|
||||
/**
|
||||
* Constant for transaction isolation level REPEATABLE READ.
|
||||
*/
|
||||
const TRANSACTION_REPEATABLE_READ = 3;
|
||||
|
||||
/**
|
||||
* Constant for transaction isolation level SERIALIZABLE.
|
||||
*/
|
||||
const TRANSACTION_SERIALIZABLE = 4;
|
||||
|
||||
/**
|
||||
* The wrapped driver connection.
|
||||
*
|
||||
* @var Doctrine\DBAL\Driver\Connection
|
||||
*/
|
||||
protected $_conn;
|
||||
|
||||
/**
|
||||
* @var Doctrine\DBAL\Configuration
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* @var Doctrine\Common\EventManager
|
||||
*/
|
||||
protected $_eventManager;
|
||||
|
||||
/**
|
||||
* Whether or not a connection has been established.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_isConnected = false;
|
||||
|
||||
/**
|
||||
* The transaction nesting level.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_transactionNestingLevel = 0;
|
||||
|
||||
/**
|
||||
* The currently active transaction isolation level.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_transactionIsolationLevel;
|
||||
|
||||
/**
|
||||
* The parameters used during creation of the Connection instance.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_params = array();
|
||||
|
||||
/**
|
||||
* The DatabasePlatform object that provides information about the
|
||||
* database platform used by the connection.
|
||||
*
|
||||
* @var Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
protected $_platform;
|
||||
|
||||
/**
|
||||
* The schema manager.
|
||||
*
|
||||
* @var Doctrine\DBAL\Schema\SchemaManager
|
||||
*/
|
||||
protected $_schemaManager;
|
||||
|
||||
/**
|
||||
* The used DBAL driver.
|
||||
*
|
||||
* @var Doctrine\DBAL\Driver
|
||||
*/
|
||||
protected $_driver;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether the current transaction is marked for rollback only.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_isRollbackOnly = false;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Connection class.
|
||||
*
|
||||
* @param array $params The connection parameters.
|
||||
* @param Driver $driver
|
||||
* @param Configuration $config
|
||||
* @param EventManager $eventManager
|
||||
*/
|
||||
public function __construct(array $params, Driver $driver, Configuration $config = null,
|
||||
EventManager $eventManager = null)
|
||||
{
|
||||
$this->_driver = $driver;
|
||||
$this->_params = $params;
|
||||
|
||||
if (isset($params['pdo'])) {
|
||||
$this->_conn = $params['pdo'];
|
||||
$this->_isConnected = true;
|
||||
}
|
||||
|
||||
// Create default config and event manager if none given
|
||||
if ( ! $config) {
|
||||
$config = new Configuration();
|
||||
}
|
||||
|
||||
if ( ! $eventManager) {
|
||||
$eventManager = new EventManager();
|
||||
}
|
||||
|
||||
$this->_config = $config;
|
||||
$this->_eventManager = $eventManager;
|
||||
if ( ! isset($params['platform'])) {
|
||||
$this->_platform = $driver->getDatabasePlatform();
|
||||
} else if ($params['platform'] instanceof Platforms\AbstractPlatform) {
|
||||
$this->_platform = $params['platform'];
|
||||
} else {
|
||||
throw DBALException::invalidPlatformSpecified();
|
||||
}
|
||||
$this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parameters used during instantiation.
|
||||
*
|
||||
* @return array $params
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the database this Connection is connected to.
|
||||
*
|
||||
* @return string $database
|
||||
*/
|
||||
public function getDatabase()
|
||||
{
|
||||
return $this->_driver->getDatabase($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hostname of the currently connected database.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return isset($this->_params['host']) ? $this->_params['host'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the port of the currently connected database.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return isset($this->_params['port']) ? $this->_params['port'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the username used by this connection.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return isset($this->_params['user']) ? $this->_params['user'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the password used by this connection.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return isset($this->_params['password']) ? $this->_params['password'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DBAL driver instance.
|
||||
*
|
||||
* @return Doctrine\DBAL\Driver
|
||||
*/
|
||||
public function getDriver()
|
||||
{
|
||||
return $this->_driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Configuration used by the Connection.
|
||||
*
|
||||
* @return Doctrine\DBAL\Configuration
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EventManager used by the Connection.
|
||||
*
|
||||
* @return Doctrine\Common\EventManager
|
||||
*/
|
||||
public function getEventManager()
|
||||
{
|
||||
return $this->_eventManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DatabasePlatform for the connection.
|
||||
*
|
||||
* @return Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return $this->_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the connection with the database.
|
||||
*
|
||||
* @return boolean TRUE if the connection was successfully established, FALSE if
|
||||
* the connection is already open.
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->_isConnected) return false;
|
||||
|
||||
$driverOptions = isset($this->_params['driverOptions']) ?
|
||||
$this->_params['driverOptions'] : array();
|
||||
$user = isset($this->_params['user']) ? $this->_params['user'] : null;
|
||||
$password = isset($this->_params['password']) ?
|
||||
$this->_params['password'] : null;
|
||||
|
||||
$this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
|
||||
$this->_isConnected = true;
|
||||
|
||||
if ($this->_eventManager->hasListeners(Events::postConnect)) {
|
||||
$eventArgs = new Event\ConnectionEventArgs($this);
|
||||
$this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and executes an SQL query and returns the first row of the result
|
||||
* as an associative array.
|
||||
*
|
||||
* @param string $statement The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAssoc($statement, array $params = array())
|
||||
{
|
||||
return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and executes an SQL query and returns the first row of the result
|
||||
* as a numerically indexed array.
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @return array
|
||||
*/
|
||||
public function fetchArray($statement, array $params = array())
|
||||
{
|
||||
return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_NUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and executes an SQL query and returns the value of a single column
|
||||
* of the first row of the result.
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @param int $colnum 0-indexed column number to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchColumn($statement, array $params = array(), $colnum = 0)
|
||||
{
|
||||
return $this->executeQuery($statement, $params)->fetchColumn($colnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an actual connection to the database is established.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return $this->_isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a transaction is currently active.
|
||||
*
|
||||
* @return boolean TRUE if a transaction is currently active, FALSE otherwise.
|
||||
*/
|
||||
public function isTransactionActive()
|
||||
{
|
||||
return $this->_transactionNestingLevel > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL DELETE statement on a table.
|
||||
*
|
||||
* @param string $table The name of the table on which to delete.
|
||||
* @param array $identifier The deletion criteria. An associateve array containing column-value pairs.
|
||||
* @return integer The number of affected rows.
|
||||
*/
|
||||
public function delete($tableName, array $identifier)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$criteria = array();
|
||||
|
||||
foreach (array_keys($identifier) as $columnName) {
|
||||
$criteria[] = $columnName . ' = ?';
|
||||
}
|
||||
|
||||
$query = 'DELETE FROM ' . $tableName . ' WHERE ' . implode(' AND ', $criteria);
|
||||
|
||||
return $this->executeUpdate($query, array_values($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
unset($this->_conn);
|
||||
|
||||
$this->_isConnected = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transaction isolation level.
|
||||
*
|
||||
* @param integer $level The level to set.
|
||||
*/
|
||||
public function setTransactionIsolation($level)
|
||||
{
|
||||
$this->_transactionIsolationLevel = $level;
|
||||
|
||||
return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently active transaction isolation level.
|
||||
*
|
||||
* @return integer The current transaction isolation level.
|
||||
*/
|
||||
public function getTransactionIsolation()
|
||||
{
|
||||
return $this->_transactionIsolationLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL UPDATE statement on a table.
|
||||
*
|
||||
* @param string $table The name of the table to update.
|
||||
* @param array $identifier The update criteria. An associative array containing column-value pairs.
|
||||
* @return integer The number of affected rows.
|
||||
*/
|
||||
public function update($tableName, array $data, array $identifier)
|
||||
{
|
||||
$this->connect();
|
||||
$set = array();
|
||||
foreach ($data as $columnName => $value) {
|
||||
$set[] = $columnName . ' = ?';
|
||||
}
|
||||
|
||||
$params = array_merge(array_values($data), array_values($identifier));
|
||||
|
||||
$sql = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $set)
|
||||
. ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
|
||||
. ' = ?';
|
||||
|
||||
return $this->executeUpdate($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a table row with specified data.
|
||||
*
|
||||
* @param string $table The name of the table to insert data into.
|
||||
* @param array $data An associative array containing column-value pairs.
|
||||
* @return integer The number of affected rows.
|
||||
*/
|
||||
public function insert($tableName, array $data)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// column names are specified as array keys
|
||||
$cols = array();
|
||||
$placeholders = array();
|
||||
|
||||
foreach ($data as $columnName => $value) {
|
||||
$cols[] = $columnName;
|
||||
$placeholders[] = '?';
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO ' . $tableName
|
||||
. ' (' . implode(', ', $cols) . ')'
|
||||
. ' VALUES (' . implode(', ', $placeholders) . ')';
|
||||
|
||||
return $this->executeUpdate($query, array_values($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given charset on the current connection.
|
||||
*
|
||||
* @param string $charset The charset to set.
|
||||
*/
|
||||
public function setCharset($charset)
|
||||
{
|
||||
$this->executeUpdate($this->_platform->getSetCharsetSQL($charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a string so it can be safely used as a table or column name, even if
|
||||
* it is a reserved name.
|
||||
*
|
||||
* Delimiting style depends on the underlying database platform that is being used.
|
||||
*
|
||||
* NOTE: Just because you CAN use quoted identifiers does not mean
|
||||
* you SHOULD use them. In general, they end up causing way more
|
||||
* problems than they solve.
|
||||
*
|
||||
* @param string $str The name to be quoted.
|
||||
* @return string The quoted name.
|
||||
*/
|
||||
public function quoteIdentifier($str)
|
||||
{
|
||||
return $this->_platform->quoteIdentifier($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a given input parameter.
|
||||
*
|
||||
* @param mixed $input Parameter to be quoted.
|
||||
* @param string $type Type of the parameter.
|
||||
* @return string The quoted parameter.
|
||||
*/
|
||||
public function quote($input, $type = null)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return $this->_conn->quote($input, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and executes an SQL query and returns the result as an associative array.
|
||||
*
|
||||
* @param string $sql The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($sql, array $params = array())
|
||||
{
|
||||
return $this->executeQuery($sql, $params)->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an SQL statement.
|
||||
*
|
||||
* @param string $statement The SQL statement to prepare.
|
||||
* @return Doctrine\DBAL\Driver\Statement The prepared statement.
|
||||
*/
|
||||
public function prepare($statement)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return new Statement($statement, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an, optionally parameterized, SQL query.
|
||||
*
|
||||
* If the query is parameterized, a prepared statement is used.
|
||||
* If an SQLLogger is configured, the execution is logged.
|
||||
*
|
||||
* @param string $query The SQL query to execute.
|
||||
* @param array $params The parameters to bind to the query, if any.
|
||||
* @return Doctrine\DBAL\Driver\Statement The executed statement.
|
||||
* @internal PERF: Directly prepares a driver statement, not a wrapper.
|
||||
*/
|
||||
public function executeQuery($query, array $params = array(), $types = array())
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if ($this->_config->getSQLLogger() !== null) {
|
||||
$this->_config->getSQLLogger()->logSQL($query, $params);
|
||||
}
|
||||
|
||||
if ($params) {
|
||||
$stmt = $this->_conn->prepare($query);
|
||||
if ($types) {
|
||||
$this->_bindTypedValues($stmt, $params, $types);
|
||||
$stmt->execute();
|
||||
} else {
|
||||
$stmt->execute($params);
|
||||
}
|
||||
} else {
|
||||
$stmt = $this->_conn->query($query);
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an, optionally parameterized, SQL query and returns the result,
|
||||
* applying a given projection/transformation function on each row of the result.
|
||||
*
|
||||
* @param string $query The SQL query to execute.
|
||||
* @param array $params The parameters, if any.
|
||||
* @param Closure $mapper The transformation function that is applied on each row.
|
||||
* The function receives a single paramater, an array, that
|
||||
* represents a row of the result set.
|
||||
* @return mixed The projected result of the query.
|
||||
*/
|
||||
public function project($query, array $params, Closure $function)
|
||||
{
|
||||
$result = array();
|
||||
$stmt = $this->executeQuery($query, $params ?: array());
|
||||
|
||||
while ($row = $stmt->fetch()) {
|
||||
$result[] = $function($row);
|
||||
}
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL statement, returning a result set as a Statement object.
|
||||
*
|
||||
* @param string $statement
|
||||
* @param integer $fetchType
|
||||
* @return Doctrine\DBAL\Driver\Statement
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return call_user_func_array(array($this->_conn, 'query'), func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
|
||||
* and returns the number of affected rows.
|
||||
*
|
||||
* This method supports PDO binding types as well as DBAL mapping types.
|
||||
*
|
||||
* @param string $query The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @param array $types The parameter types.
|
||||
* @return integer The number of affected rows.
|
||||
* @internal PERF: Directly prepares a driver statement, not a wrapper.
|
||||
*/
|
||||
public function executeUpdate($query, array $params = array(), array $types = array())
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if ($this->_config->getSQLLogger() !== null) {
|
||||
$this->_config->getSQLLogger()->logSQL($query, $params);
|
||||
}
|
||||
|
||||
if ($params) {
|
||||
$stmt = $this->_conn->prepare($query);
|
||||
if ($types) {
|
||||
$this->_bindTypedValues($stmt, $params, $types);
|
||||
$stmt->execute();
|
||||
} else {
|
||||
$stmt->execute($params);
|
||||
}
|
||||
$result = $stmt->rowCount();
|
||||
} else {
|
||||
$result = $this->_conn->exec($query);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an SQL statement and return the number of affected rows.
|
||||
*
|
||||
* @param string $statement
|
||||
* @return integer The number of affected rows.
|
||||
*/
|
||||
public function exec($statement)
|
||||
{
|
||||
$this->connect();
|
||||
return $this->_conn->exec($statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current transaction nesting level.
|
||||
*
|
||||
* @return integer The nesting level. A value of 0 means there's no active transaction.
|
||||
*/
|
||||
public function getTransactionNestingLevel()
|
||||
{
|
||||
return $this->_transactionNestingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the SQLSTATE associated with the last database operation.
|
||||
*
|
||||
* @return integer The last error code.
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->_conn->errorCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch extended error information associated with the last database operation.
|
||||
*
|
||||
* @return array The last error information.
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->_conn->errorInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the last inserted row, or the last value from a sequence object,
|
||||
* depending on the underlying driver.
|
||||
*
|
||||
* Note: This method may not return a meaningful or consistent result across different drivers,
|
||||
* because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
|
||||
* columns or sequences.
|
||||
*
|
||||
* @param string $seqName Name of the sequence object from which the ID should be returned.
|
||||
* @return string A string representation of the last inserted ID.
|
||||
*/
|
||||
public function lastInsertId($seqName = null)
|
||||
{
|
||||
$this->connect();
|
||||
return $this->_conn->lastInsertId($seqName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a function in a transaction.
|
||||
*
|
||||
* The function gets passed this Connection instance as an (optional) parameter.
|
||||
*
|
||||
* If an exception occurs during execution of the function or transaction commit,
|
||||
* the transaction is rolled back and the exception re-thrown.
|
||||
*
|
||||
* @param Closure $func The function to execute transactionally.
|
||||
*/
|
||||
public function transactional(Closure $func)
|
||||
{
|
||||
$this->beginTransaction();
|
||||
try {
|
||||
$func($this);
|
||||
$this->commit();
|
||||
} catch (Exception $e) {
|
||||
$this->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transaction by suspending auto-commit mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
$this->_conn->beginTransaction();
|
||||
}
|
||||
|
||||
++$this->_transactionNestingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the current transaction.
|
||||
*
|
||||
* @return void
|
||||
* @throws ConnectionException If the commit failed due to no active transaction or
|
||||
* because the transaction was marked for rollback only.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
throw ConnectionException::noActiveTransaction();
|
||||
}
|
||||
if ($this->_isRollbackOnly) {
|
||||
throw ConnectionException::commitFailedRollbackOnly();
|
||||
}
|
||||
|
||||
$this->connect();
|
||||
|
||||
if ($this->_transactionNestingLevel == 1) {
|
||||
$this->_conn->commit();
|
||||
}
|
||||
|
||||
--$this->_transactionNestingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during the current transaction.
|
||||
*
|
||||
* this method can be listened with onPreTransactionRollback and onTransactionRollback
|
||||
* eventlistener methods
|
||||
*
|
||||
* @throws ConnectionException If the rollback operation failed.
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
throw ConnectionException::noActiveTransaction();
|
||||
}
|
||||
|
||||
$this->connect();
|
||||
|
||||
if ($this->_transactionNestingLevel == 1) {
|
||||
$this->_transactionNestingLevel = 0;
|
||||
$this->_conn->rollback();
|
||||
$this->_isRollbackOnly = false;
|
||||
} else {
|
||||
$this->_isRollbackOnly = true;
|
||||
--$this->_transactionNestingLevel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapped driver connection.
|
||||
*
|
||||
* @return Doctrine\DBAL\Driver\Connection
|
||||
*/
|
||||
public function getWrappedConnection()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return $this->_conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SchemaManager that can be used to inspect or change the
|
||||
* database schema through the connection.
|
||||
*
|
||||
* @return Doctrine\DBAL\Schema\SchemaManager
|
||||
*/
|
||||
public function getSchemaManager()
|
||||
{
|
||||
if ( ! $this->_schemaManager) {
|
||||
$this->_schemaManager = $this->_driver->getSchemaManager($this);
|
||||
}
|
||||
|
||||
return $this->_schemaManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the current transaction so that the only possible
|
||||
* outcome for the transaction to be rolled back.
|
||||
*
|
||||
* @throws ConnectionException If no transaction is active.
|
||||
*/
|
||||
public function setRollbackOnly()
|
||||
{
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
throw ConnectionException::noActiveTransaction();
|
||||
}
|
||||
$this->_isRollbackOnly = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current transaction is marked for rollback only.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws ConnectionException If no transaction is active.
|
||||
*/
|
||||
public function isRollbackOnly()
|
||||
{
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
throw ConnectionException::noActiveTransaction();
|
||||
}
|
||||
return $this->_isRollbackOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given value to its database representation according to the conversion
|
||||
* rules of a specific DBAL mapping type.
|
||||
*
|
||||
* @param mixed $value The value to convert.
|
||||
* @param string $type The name of the DBAL mapping type.
|
||||
* @return mixed The converted value.
|
||||
*/
|
||||
public function convertToDatabaseValue($value, $type)
|
||||
{
|
||||
return Type::getType($type)->convertToDatabaseValue($value, $this->_platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given value to its PHP representation according to the conversion
|
||||
* rules of a specific DBAL mapping type.
|
||||
*
|
||||
* @param mixed $value The value to convert.
|
||||
* @param string $type The name of the DBAL mapping type.
|
||||
* @return mixed The converted type.
|
||||
*/
|
||||
public function convertToPHPValue($value, $type)
|
||||
{
|
||||
return Type::getType($type)->convertToPHPValue($value, $this->_platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a set of parameters, some or all of which are typed with a PDO binding type
|
||||
* or DBAL mapping type, to a given statement.
|
||||
*
|
||||
* @param $stmt The statement to bind the values to.
|
||||
* @param array $params The map/list of named/positional parameters.
|
||||
* @param array $types The parameter types (PDO binding types or DBAL mapping types).
|
||||
* @internal Duck-typing used on the $stmt parameter to support driver statements as well as
|
||||
* raw PDOStatement instances.
|
||||
*/
|
||||
private function _bindTypedValues($stmt, array $params, array $types)
|
||||
{
|
||||
// Check whether parameters are positional or named. Mixing is not allowed, just like in PDO.
|
||||
if (is_int(key($params))) {
|
||||
// Positional parameters
|
||||
$typeOffset = isset($types[0]) ? -1 : 0;
|
||||
$bindIndex = 1;
|
||||
foreach ($params as $position => $value) {
|
||||
$typeIndex = $bindIndex + $typeOffset;
|
||||
if (isset($types[$typeIndex])) {
|
||||
$type = $types[$typeIndex];
|
||||
if (is_string($type)) {
|
||||
$type = Type::getType($type);
|
||||
}
|
||||
if ($type instanceof Type) {
|
||||
$value = $type->convertToDatabaseValue($value, $this->_platform);
|
||||
$bindingType = $type->getBindingType();
|
||||
} else {
|
||||
$bindingType = $type; // PDO::PARAM_* constants
|
||||
}
|
||||
$stmt->bindValue($bindIndex, $value, $bindingType);
|
||||
} else {
|
||||
$stmt->bindValue($bindIndex, $value);
|
||||
}
|
||||
++$bindIndex;
|
||||
}
|
||||
} else {
|
||||
// Named parameters
|
||||
foreach ($params as $name => $value) {
|
||||
if (isset($types[$name])) {
|
||||
$type = $types[$name];
|
||||
if (is_string($type)) {
|
||||
$type = Type::getType($type);
|
||||
}
|
||||
if ($type instanceof Type) {
|
||||
$value = $type->convertToDatabaseValue($value, $this->_platform);
|
||||
$bindingType = $type->getBindingType();
|
||||
} else {
|
||||
$bindingType = $type; // PDO::PARAM_* constants
|
||||
}
|
||||
$stmt->bindValue($name, $value, $bindingType);
|
||||
} else {
|
||||
$stmt->bindValue($name, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Exception.php 4628 2008-07-04 16:32:19Z romanb $
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Doctrine\DBAL\ConnectionException
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 4628 $
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com
|
||||
*/
|
||||
class ConnectionException extends DBALException
|
||||
{
|
||||
public static function commitFailedRollbackOnly()
|
||||
{
|
||||
return new self("Transaction commit failed because the transaction has been marked for rollback only.");
|
||||
}
|
||||
|
||||
public static function noActiveTransaction()
|
||||
{
|
||||
return new self("There is no active transaction.");
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
class DBALException extends \Exception
|
||||
{
|
||||
public static function notSupported($method)
|
||||
{
|
||||
return new self("Operation '$method' is not supported by platform.");
|
||||
}
|
||||
|
||||
public static function invalidPlatformSpecified()
|
||||
{
|
||||
return new self(
|
||||
"Invalid 'platform' option specified, need to give an instance of ".
|
||||
"\Doctrine\DBAL\Platforms\AbstractPlatform.");
|
||||
}
|
||||
|
||||
public static function invalidPdoInstance()
|
||||
{
|
||||
return new self(
|
||||
"The 'pdo' option was used in DriverManager::getConnection() but no ".
|
||||
"instance of PDO was given."
|
||||
);
|
||||
}
|
||||
|
||||
public static function driverRequired()
|
||||
{
|
||||
return new self("The options 'driver' or 'driverClass' are mandatory if no PDO ".
|
||||
"instance is given to DriverManager::getConnection().");
|
||||
}
|
||||
|
||||
public static function unknownDriver($unknownDriverName, array $knownDrivers)
|
||||
{
|
||||
return new self("The given 'driver' ".$unknownDriverName." is unknown, ".
|
||||
"Doctrine currently supports only the following drivers: ".implode(", ", $knownDrivers));
|
||||
}
|
||||
|
||||
public static function invalidWrapperClass($wrapperClass)
|
||||
{
|
||||
return new self("The given 'wrapperClass' ".$wrapperClass." has to be a ".
|
||||
"subtype of \Doctrine\DBAL\Connection.");
|
||||
}
|
||||
|
||||
public static function invalidDriverClass($driverClass)
|
||||
{
|
||||
return new self("The given 'driverClass' ".$driverClass." has to implement the ".
|
||||
"\Doctrine\DBAL\Driver interface.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return DBALException
|
||||
*/
|
||||
public static function invalidTableName($tableName)
|
||||
{
|
||||
return new self("Invalid table name specified: ".$tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return DBALException
|
||||
*/
|
||||
public static function noColumnsSpecifiedForTable($tableName)
|
||||
{
|
||||
return new self("No columns specified for table ".$tableName);
|
||||
}
|
||||
|
||||
public static function limitOffsetInvalid()
|
||||
{
|
||||
return new self("Invalid Offset in Limit Query, it has to be larger or equal to 0.");
|
||||
}
|
||||
|
||||
public static function typeExists($name)
|
||||
{
|
||||
return new self('Type '.$name.' already exists.');
|
||||
}
|
||||
|
||||
public static function unknownColumnType($name)
|
||||
{
|
||||
return new self('Unknown column type '.$name.' requested.');
|
||||
}
|
||||
|
||||
public static function typeNotFound($name)
|
||||
{
|
||||
return new self('Type to be overwritten '.$name.' does not exist.');
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Driver interface.
|
||||
* Interface that all DBAL drivers must implement.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
interface Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to create a connection with the database.
|
||||
*
|
||||
* @param array $params All connection parameters passed by the user.
|
||||
* @param string $username The username to use when connecting.
|
||||
* @param string $password The password to use when connecting.
|
||||
* @param array $driverOptions The driver options to use when connecting.
|
||||
* @return Doctrine\DBAL\Driver\Connection The database connection.
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array());
|
||||
|
||||
/**
|
||||
* Gets the DatabasePlatform instance that provides all the metadata about
|
||||
* the platform this driver connects to.
|
||||
*
|
||||
* @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
|
||||
*/
|
||||
public function getDatabasePlatform();
|
||||
|
||||
/**
|
||||
* Gets the SchemaManager that can be used to inspect and change the underlying
|
||||
* database schema of the platform this driver connects to.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return Doctrine\DBAL\SchemaManager
|
||||
*/
|
||||
public function getSchemaManager(Connection $conn);
|
||||
|
||||
/**
|
||||
* Gets the name of the driver.
|
||||
*
|
||||
* @return string The name of the driver.
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get the name of the database connected to for this driver.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return string $database
|
||||
*/
|
||||
public function getDatabase(Connection $conn);
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Driver;
|
||||
|
||||
/**
|
||||
* Connection interface.
|
||||
* Driver connections must implement this interface.
|
||||
*
|
||||
* This resembles (a subset of) the PDO interface.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
interface Connection
|
||||
{
|
||||
function prepare($prepareString);
|
||||
function query();
|
||||
function quote($input, $type=\PDO::PARAM_STR);
|
||||
function exec($statement);
|
||||
function lastInsertId($name = null);
|
||||
function beginTransaction();
|
||||
function commit();
|
||||
function rollBack();
|
||||
function errorCode();
|
||||
function errorInfo();
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
<?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\Driver\IBMDB2;
|
||||
|
||||
class DB2Connection implements \Doctrine\DBAL\Driver\Connection
|
||||
{
|
||||
private $_conn = null;
|
||||
|
||||
public function __construct(array $params, $username, $password, $driverOptions = array())
|
||||
{
|
||||
$isPersistant = (isset($params['persistent']) && $params['persistent'] == true);
|
||||
|
||||
if ($isPersistant) {
|
||||
$this->_conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
|
||||
} else {
|
||||
$this->_conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
|
||||
}
|
||||
if (!$this->_conn) {
|
||||
throw new DB2Exception(db2_conn_errormsg());
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($sql)
|
||||
{
|
||||
$stmt = @db2_prepare($this->_conn, $sql);
|
||||
if (!$stmt) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
}
|
||||
return new DB2Statement($stmt);
|
||||
}
|
||||
|
||||
function query()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$sql = $args[0];
|
||||
$stmt = $this->prepare($sql);
|
||||
$stmt->execute();
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function quote($input, $type=\PDO::PARAM_STR)
|
||||
{
|
||||
$input = db2_escape_string($input);
|
||||
if ($type == \PDO::PARAM_INT ) {
|
||||
return $input;
|
||||
} else {
|
||||
return "'".$input."'";
|
||||
}
|
||||
}
|
||||
|
||||
function exec($statement)
|
||||
{
|
||||
$stmt = $this->prepare($statement);
|
||||
$stmt->execute();
|
||||
return $stmt->rowCount();
|
||||
}
|
||||
|
||||
function lastInsertId($name = null)
|
||||
{
|
||||
return db2_last_insert_id($this->_conn);
|
||||
}
|
||||
|
||||
function beginTransaction()
|
||||
{
|
||||
db2_autocommit($this->_conn, DB2_AUTOCOMMIT_OFF);
|
||||
}
|
||||
|
||||
function commit()
|
||||
{
|
||||
if (!db2_commit($this->_conn)) {
|
||||
throw new DB2Exception(db2_conn_errormsg($this->_conn));
|
||||
}
|
||||
db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
|
||||
}
|
||||
|
||||
function rollBack()
|
||||
{
|
||||
if (!db2_rollback($this->_conn)) {
|
||||
throw new DB2Exception(db2_conn_errormsg($this->_conn));
|
||||
}
|
||||
db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
|
||||
}
|
||||
|
||||
function errorCode()
|
||||
{
|
||||
return db2_conn_error($this->_conn);
|
||||
}
|
||||
|
||||
function errorInfo()
|
||||
{
|
||||
return array(
|
||||
0 => db2_conn_errormsg($this->_conn),
|
||||
1 => $this->errorCode(),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Driver\IBMDB2;
|
||||
|
||||
use Doctrine\DBAL\Driver,
|
||||
Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* IBM DB2 Driver
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class DB2Driver implements Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to create a connection with the database.
|
||||
*
|
||||
* @param array $params All connection parameters passed by the user.
|
||||
* @param string $username The username to use when connecting.
|
||||
* @param string $password The password to use when connecting.
|
||||
* @param array $driverOptions The driver options to use when connecting.
|
||||
* @return Doctrine\DBAL\Driver\Connection The database connection.
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
if ( !isset($params['schema']) ) {
|
||||
|
||||
}
|
||||
|
||||
if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') {
|
||||
// if the host isn't localhost, use extended connection params
|
||||
$params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' .
|
||||
';DATABASE=' . $params['dbname'] .
|
||||
';HOSTNAME=' . $params['host'] .
|
||||
';PORT=' . $params['port'] .
|
||||
';PROTOCOL=' . $params['protocol'] .
|
||||
';UID=' . $username .
|
||||
';PWD=' . $password .';';
|
||||
$username = null;
|
||||
$password = null;
|
||||
}
|
||||
|
||||
return new DB2Connection($params, $username, $password, $driverOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DatabasePlatform instance that provides all the metadata about
|
||||
* the platform this driver connects to.
|
||||
*
|
||||
* @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\DB2Platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SchemaManager that can be used to inspect and change the underlying
|
||||
* database schema of the platform this driver connects to.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return Doctrine\DBAL\SchemaManager
|
||||
*/
|
||||
public function getSchemaManager(Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the driver.
|
||||
*
|
||||
* @return string The name of the driver.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'ibm_db2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the database connected to for this driver.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return string $database
|
||||
*/
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['dbname'];
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?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\Driver\IBMDB2;
|
||||
|
||||
class DB2Exception extends \Exception
|
||||
{
|
||||
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
<?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\Driver\IBMDB2;
|
||||
|
||||
class DB2Statement implements \Doctrine\DBAL\Driver\Statement
|
||||
{
|
||||
private $_stmt = null;
|
||||
|
||||
private $_bindParam = array();
|
||||
|
||||
/**
|
||||
* DB2_BINARY, DB2_CHAR, DB2_DOUBLE, or DB2_LONG
|
||||
* @var <type>
|
||||
*/
|
||||
static private $_typeMap = array(
|
||||
\PDO::PARAM_INT => DB2_LONG,
|
||||
\PDO::PARAM_STR => DB2_CHAR,
|
||||
);
|
||||
|
||||
public function __construct($stmt)
|
||||
{
|
||||
$this->_stmt = $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a value to a corresponding named or positional
|
||||
* placeholder in the SQL statement that was used to prepare the statement.
|
||||
*
|
||||
* @param mixed $param Parameter identifier. For a prepared statement using named placeholders,
|
||||
* this will be a parameter name of the form :name. For a prepared statement
|
||||
* using question mark placeholders, this will be the 1-indexed position of the parameter
|
||||
*
|
||||
* @param mixed $value The value to bind to the parameter.
|
||||
* @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function bindValue($param, $value, $type = null)
|
||||
{
|
||||
return $this->bindParam($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a PHP variable to a corresponding named or question mark placeholder in the
|
||||
* SQL statement that was use to prepare the statement. Unlike PDOStatement->bindValue(),
|
||||
* the variable is bound as a reference and will only be evaluated at the time
|
||||
* that PDOStatement->execute() is called.
|
||||
*
|
||||
* Most parameters are input parameters, that is, parameters that are
|
||||
* used in a read-only fashion to build up the query. Some drivers support the invocation
|
||||
* of stored procedures that return data as output parameters, and some also as input/output
|
||||
* parameters that both send in data and are updated to receive it.
|
||||
*
|
||||
* @param mixed $param Parameter identifier. For a prepared statement using named placeholders,
|
||||
* this will be a parameter name of the form :name. For a prepared statement
|
||||
* using question mark placeholders, this will be the 1-indexed position of the parameter
|
||||
*
|
||||
* @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
|
||||
*
|
||||
* @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants. To return
|
||||
* an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
|
||||
* PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function bindParam($column, &$variable, $type = null)
|
||||
{
|
||||
$this->_bindParam[$column] =& $variable;
|
||||
|
||||
if ($type && isset(self::$_typeMap[$type])) {
|
||||
$type = self::$_typeMap[$type];
|
||||
} else {
|
||||
$type = DB2_CHAR;
|
||||
}
|
||||
|
||||
if (!db2_bind_param($this->_stmt, $column, "variable", DB2_PARAM_IN, $type)) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the cursor, enabling the statement to be executed again.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function closeCursor()
|
||||
{
|
||||
if (!$this->_stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_bindParam = array();
|
||||
db2_free_result($this->_stmt);
|
||||
$ret = db2_free_stmt($this->_stmt);
|
||||
$this->_stmt = false;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* columnCount
|
||||
* Returns the number of columns in the result set
|
||||
*
|
||||
* @return integer Returns the number of columns in the result set represented
|
||||
* by the PDOStatement object. If there is no result set,
|
||||
* this method should return 0.
|
||||
*/
|
||||
function columnCount()
|
||||
{
|
||||
if (!$this->_stmt) {
|
||||
return false;
|
||||
}
|
||||
return db2_num_fields($this->_stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* errorCode
|
||||
* Fetch the SQLSTATE associated with the last operation on the statement handle
|
||||
*
|
||||
* @see Doctrine_Adapter_Interface::errorCode()
|
||||
* @return string error code string
|
||||
*/
|
||||
function errorCode()
|
||||
{
|
||||
return db2_stmt_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* errorInfo
|
||||
* Fetch extended error information associated with the last operation on the statement handle
|
||||
*
|
||||
* @see Doctrine_Adapter_Interface::errorInfo()
|
||||
* @return array error info array
|
||||
*/
|
||||
function errorInfo()
|
||||
{
|
||||
return array(
|
||||
0 => db2_stmt_errormsg(),
|
||||
1 => db2_stmt_error(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a prepared statement
|
||||
*
|
||||
* If the prepared statement included parameter markers, you must either:
|
||||
* call PDOStatement->bindParam() to bind PHP variables to the parameter markers:
|
||||
* bound variables pass their value as input and receive the output value,
|
||||
* if any, of their associated parameter markers or pass an array of input-only
|
||||
* parameter values
|
||||
*
|
||||
*
|
||||
* @param array $params An array of values with as many elements as there are
|
||||
* bound parameters in the SQL statement being executed.
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function execute($params = null)
|
||||
{
|
||||
if (!$this->_stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*$retval = true;
|
||||
if ($params !== null) {
|
||||
$retval = @db2_execute($this->_stmt, $params);
|
||||
} else {
|
||||
$retval = @db2_execute($this->_stmt);
|
||||
}*/
|
||||
if ($params === null) {
|
||||
ksort($this->_bindParam);
|
||||
$params = array_values($this->_bindParam);
|
||||
}
|
||||
$retval = @db2_execute($this->_stmt, $params);
|
||||
|
||||
if ($retval === false) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch
|
||||
*
|
||||
* @see Query::HYDRATE_* constants
|
||||
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_* constants,
|
||||
* defaulting to Query::HYDRATE_BOTH
|
||||
*
|
||||
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
|
||||
* this value determines which row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
|
||||
* Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
|
||||
* PDOStatement object,
|
||||
* you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
|
||||
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
|
||||
*
|
||||
* @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the
|
||||
* $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
|
||||
* the absolute number of the row in the result set that shall be fetched.
|
||||
*
|
||||
* For a PDOStatement object representing a scrollable cursor for
|
||||
* which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
|
||||
* specifies the row to fetch relative to the cursor position before
|
||||
* PDOStatement->fetch() was called.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function fetch($fetchStyle = \PDO::FETCH_BOTH)
|
||||
{
|
||||
switch ($fetchStyle) {
|
||||
case \PDO::FETCH_BOTH:
|
||||
return db2_fetch_both($this->_stmt);
|
||||
case \PDO::FETCH_ASSOC:
|
||||
return db2_fetch_assoc($this->_stmt);
|
||||
case \PDO::FETCH_NUM:
|
||||
return db2_fetch_array($this->_stmt);
|
||||
default:
|
||||
throw new DB2Exception("Given Fetch-Style " . $fetchStyle . " is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the result set rows
|
||||
*
|
||||
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_* constants,
|
||||
* defaulting to Query::HYDRATE_BOTH
|
||||
*
|
||||
* @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is
|
||||
* Query::HYDRATE_COLUMN. Defaults to 0.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function fetchAll($fetchStyle = \PDO::FETCH_BOTH)
|
||||
{
|
||||
$rows = array();
|
||||
while ($row = $this->fetch($fetchStyle)) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchColumn
|
||||
* Returns a single column from the next row of a
|
||||
* result set or FALSE if there are no more rows.
|
||||
*
|
||||
* @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no
|
||||
* value is supplied, PDOStatement->fetchColumn()
|
||||
* fetches the first column.
|
||||
*
|
||||
* @return string returns a single column in the next row of a result set.
|
||||
*/
|
||||
function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
$row = $this->fetch(\PDO::FETCH_NUM);
|
||||
if ($row && isset($row[$columnIndex])) {
|
||||
return $row[$columnIndex];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rowCount
|
||||
* rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
|
||||
* executed by the corresponding object.
|
||||
*
|
||||
* If the last SQL statement executed by the associated Statement object was a SELECT statement,
|
||||
* some databases may return the number of rows returned by that statement. However,
|
||||
* this behaviour is not guaranteed for all databases and should not be
|
||||
* relied on for portable applications.
|
||||
*
|
||||
* @return integer Returns the number of rows.
|
||||
*/
|
||||
function rowCount()
|
||||
{
|
||||
return (@db2_num_rows($this->_stmt))?:0;
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?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\Driver\OCI8;
|
||||
|
||||
use Doctrine\DBAL\Platforms;
|
||||
|
||||
/**
|
||||
* A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
return new OCI8Connection(
|
||||
$username,
|
||||
$password,
|
||||
$this->_constructDsn($params)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Oracle DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructDsn(array $params)
|
||||
{
|
||||
$dsn = '';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
|
||||
'(HOST=' . $params['host'] . ')';
|
||||
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= '(PORT=' . $params['port'] . ')';
|
||||
} else {
|
||||
$dsn .= '(PORT=1521)';
|
||||
}
|
||||
|
||||
$dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
|
||||
} else {
|
||||
$dsn .= $params['dbname'];
|
||||
}
|
||||
|
||||
if (isset($params['charset'])) {
|
||||
$dsn .= ';charset=' . $params['charset'];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\OraclePlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'oci8';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['user'];
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?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\Driver\OCI8;
|
||||
|
||||
/**
|
||||
* OCI8 implementation of the Connection interface.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class OCI8Connection implements \Doctrine\DBAL\Driver\Connection
|
||||
{
|
||||
private $_dbh;
|
||||
|
||||
public function __construct($username, $password, $db)
|
||||
{
|
||||
$this->_dbh = @oci_connect($username, $password, $db);
|
||||
if (!$this->_dbh) {
|
||||
throw new OCI8Exception($this->errorInfo());
|
||||
}
|
||||
}
|
||||
|
||||
public function prepare($prepareString)
|
||||
{
|
||||
return new OCI8Statement($this->_dbh, $prepareString);
|
||||
}
|
||||
|
||||
public function query()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$sql = $args[0];
|
||||
//$fetchMode = $args[1];
|
||||
$stmt = $this->prepare($sql);
|
||||
$stmt->execute();
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
public function quote($input, $type=\PDO::PARAM_STR)
|
||||
{
|
||||
return is_numeric($input) ? $input : "'$input'";
|
||||
}
|
||||
|
||||
public function exec($statement)
|
||||
{
|
||||
$stmt = $this->prepare($statement);
|
||||
$stmt->execute();
|
||||
return $stmt->rowCount();
|
||||
}
|
||||
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
//TODO: throw exception or support sequences?
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
if (!oci_commit($this->_dbh)) {
|
||||
throw OCI8Exception::fromErrorInfo($this->errorInfo());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
if (!oci_rollback($this->_dbh)) {
|
||||
throw OCI8Exception::fromErrorInfo($this->errorInfo());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function errorCode()
|
||||
{
|
||||
$error = oci_error($this->_dbh);
|
||||
if ($error !== false) {
|
||||
$error = $error['code'];
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
public function errorInfo()
|
||||
{
|
||||
return oci_error($this->_dbh);
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?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\Driver\OCI8;
|
||||
|
||||
class OCI8Exception extends \Exception
|
||||
{
|
||||
static public function fromErrorInfo($error)
|
||||
{
|
||||
return new self($error['message'], $error['code']);
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Interface.php 3882 2008-02-22 18:11:35Z jwage $
|
||||
*
|
||||
* 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\Driver\OCI8;
|
||||
|
||||
use \PDO;
|
||||
|
||||
/**
|
||||
* The OCI8 implementation of the Statement interface.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
|
||||
{
|
||||
/** Statement handle. */
|
||||
private $_sth;
|
||||
private $_paramCounter = 0;
|
||||
private static $_PARAM = ':param';
|
||||
private static $fetchStyleMap = array(
|
||||
PDO::FETCH_BOTH => OCI_BOTH,
|
||||
PDO::FETCH_ASSOC => OCI_ASSOC,
|
||||
PDO::FETCH_NUM => OCI_NUM
|
||||
);
|
||||
private $_paramMap = array();
|
||||
|
||||
/**
|
||||
* Creates a new OCI8Statement that uses the given connection handle and SQL statement.
|
||||
*
|
||||
* @param resource $dbh The connection handle.
|
||||
* @param string $statement The SQL statement.
|
||||
*/
|
||||
public function __construct($dbh, $statement)
|
||||
{
|
||||
$this->_sth = oci_parse($dbh, $this->_convertPositionalToNamedPlaceholders($statement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle does not support positional parameters, hence this method converts all
|
||||
* positional parameters into artificially named parameters. Note that this conversion
|
||||
* is not perfect. All question marks (?) in the original statement are treated as
|
||||
* placeholders and converted to a named parameter.
|
||||
*
|
||||
* @param string $statement The SQL statement to convert.
|
||||
* @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements.
|
||||
*/
|
||||
private function _convertPositionalToNamedPlaceholders($statement)
|
||||
{
|
||||
$count = 1;
|
||||
while (($pos = strpos($statement, '?')) !== false) {
|
||||
$this->_paramMap[$count] = ":param$count";
|
||||
$statement = substr_replace($statement, ":param$count", $pos, 1);
|
||||
++$count;
|
||||
}
|
||||
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindValue($param, $value, $type = null)
|
||||
{
|
||||
return $this->bindParam($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = null)
|
||||
{
|
||||
$column = isset($this->_paramMap[$column]) ? $this->_paramMap[$column] : $column;
|
||||
|
||||
return oci_bind_by_name($this->_sth, $column, $variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the cursor, enabling the statement to be executed again.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
return oci_free_statement($this->_sth);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function columnCount()
|
||||
{
|
||||
return oci_num_fields($this->_sth);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
$error = oci_error($this->_sth);
|
||||
if ($error !== false) {
|
||||
$error = $error['code'];
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
return oci_error($this->_sth);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($params = null)
|
||||
{
|
||||
if ($params) {
|
||||
$hasZeroIndex = isset($params[0]);
|
||||
foreach ($params as $key => $val) {
|
||||
if ($hasZeroIndex && is_numeric($key)) {
|
||||
$this->bindValue($key + 1, $val);
|
||||
} else {
|
||||
$this->bindValue($key, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ret = @oci_execute($this->_sth, OCI_DEFAULT);
|
||||
if ( ! $ret) {
|
||||
throw OCI8Exception::fromErrorInfo($this->errorInfo());
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($fetchStyle = PDO::FETCH_BOTH)
|
||||
{
|
||||
if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
|
||||
throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
|
||||
}
|
||||
|
||||
return oci_fetch_array($this->_sth, self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($fetchStyle = PDO::FETCH_BOTH)
|
||||
{
|
||||
if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
|
||||
throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
oci_fetch_all($this->_sth, $result, 0, -1,
|
||||
self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_FETCHSTATEMENT_BY_ROW | OCI_RETURN_LOBS);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
$row = oci_fetch_row($this->_sth);
|
||||
return $row[$columnIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rowCount()
|
||||
{
|
||||
return oci_num_rows($this->_sth);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?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\Driver;
|
||||
|
||||
use \PDO;
|
||||
|
||||
/**
|
||||
* PDO implementation of the Connection interface.
|
||||
* Used by all PDO-based drivers.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class PDOConnection extends PDO implements Connection
|
||||
{
|
||||
public function __construct($dsn, $user = null, $password = null, array $options = null)
|
||||
{
|
||||
parent::__construct($dsn, $user, $password, $options);
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine\DBAL\Driver\PDOStatement', array()));
|
||||
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
<?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\Driver\PDOIbm;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* Driver for the PDO IBM extension
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to establish a connection with the underlying driver.
|
||||
*
|
||||
* @param array $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param array $driverOptions
|
||||
* @return Doctrine\DBAL\Driver\Connection
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
$conn = new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the MySql PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
$dsn = 'ibm:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'HOSTNAME=' . $params['host'] . ';';
|
||||
}
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'PORT=' . $params['port'] . ';';
|
||||
}
|
||||
$dsn .= 'PROTOCOL=TCPIP;';
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'DATABASE=' . $params['dbname'] . ';';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DatabasePlatform instance that provides all the metadata about
|
||||
* the platform this driver connects to.
|
||||
*
|
||||
* @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\DB2Platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SchemaManager that can be used to inspect and change the underlying
|
||||
* database schema of the platform this driver connects to.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return Doctrine\DBAL\SchemaManager
|
||||
*/
|
||||
public function getSchemaManager(Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the driver.
|
||||
*
|
||||
* @return string The name of the driver.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_ibm';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the database connected to for this driver.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return string $database
|
||||
*/
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['dbname'];
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Driver\PDOMsSql;
|
||||
|
||||
use PDO, Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
|
||||
/**
|
||||
* MsSql Connection implementation.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Connection extends PDO implements DriverConnection
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->exec('ROLLBACK TRANSACTION');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->exec('COMMIT TRANSACTION');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->exec('BEGIN TRANSACTION');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
$stmt = $this->query('SELECT SCOPE_IDENTITY()');
|
||||
$id = $stmt->fetchColumn();
|
||||
$stmt->closeCursor();
|
||||
return $id;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?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\Driver\PDOMsSql;
|
||||
|
||||
/**
|
||||
* The PDO-based MsSql driver.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
return new Connection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the MsSql PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
// TODO: This might need to be revisted once we have access to a mssql server
|
||||
$dsn = 'mssql:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'host=' . $params['host'] . ';';
|
||||
}
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'port=' . $params['port'] . ';';
|
||||
}
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'dbname=' . $params['dbname'] . ';';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\MsSqlPlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\MsSqlSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_mssql';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['dbname'];
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Driver\PDOMySql;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* PDO MySql driver.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to establish a connection with the underlying driver.
|
||||
*
|
||||
* @param array $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param array $driverOptions
|
||||
* @return Doctrine\DBAL\Driver\Connection
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
$conn = new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the MySql PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
$dsn = 'mysql:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'host=' . $params['host'] . ';';
|
||||
}
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'port=' . $params['port'] . ';';
|
||||
}
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'dbname=' . $params['dbname'] . ';';
|
||||
}
|
||||
if (isset($params['unix_socket'])) {
|
||||
$dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\MySqlPlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_mysql';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['dbname'];
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?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\Driver\PDOOracle;
|
||||
|
||||
use Doctrine\DBAL\Platforms;
|
||||
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
return new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Oracle PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
$dsn = 'oci:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
|
||||
'(HOST=' . $params['host'] . ')';
|
||||
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= '(PORT=' . $params['port'] . ')';
|
||||
} else {
|
||||
$dsn .= '(PORT=1521)';
|
||||
}
|
||||
|
||||
$dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
|
||||
} else {
|
||||
$dsn .= 'dbname=' . $params['dbname'];
|
||||
}
|
||||
|
||||
if (isset($params['charset'])) {
|
||||
$dsn .= ';charset=' . $params['charset'];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\OraclePlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_oracle';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['user'];
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOPgSql;
|
||||
|
||||
use Doctrine\DBAL\Platforms;
|
||||
|
||||
/**
|
||||
* Driver that connects through pdo_pgsql.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to connect to the database and returns a driver connection on success.
|
||||
*
|
||||
* @return Doctrine\DBAL\Driver\Connection
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
return new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Postgres PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
$dsn = 'pgsql:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'host=' . $params['host'] . ' ';
|
||||
}
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'port=' . $params['port'] . ' ';
|
||||
}
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'dbname=' . $params['dbname'] . ' ';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\PostgreSqlPlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\PostgreSqlSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_pgsql';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return $params['dbname'];
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\Driver\PDOSqlite;
|
||||
|
||||
/**
|
||||
* The PDO Sqlite driver.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_userDefinedFunctions = array(
|
||||
'sqrt' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfSqrt'), 'numArgs' => 1),
|
||||
'mod' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfMod'), 'numArgs' => 2),
|
||||
'locate' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfLocate'), 'numArgs' => -1),
|
||||
);
|
||||
|
||||
/**
|
||||
* Tries to establish a database connection to SQLite.
|
||||
*
|
||||
* @param array $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param array $driverOptions
|
||||
* @return Connection
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
if (isset($driverOptions['userDefinedFunctions'])) {
|
||||
$this->_userDefinedFunctions = array_merge(
|
||||
$this->_userDefinedFunctions, $driverOptions['userDefinedFunctions']);
|
||||
unset($driverOptions['userDefinedFunctions']);
|
||||
}
|
||||
|
||||
$pdo = new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
|
||||
foreach ($this->_userDefinedFunctions AS $fn => $data) {
|
||||
$pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']);
|
||||
}
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Sqlite PDO DSN.
|
||||
*
|
||||
* @return string The DSN.
|
||||
* @override
|
||||
*/
|
||||
protected function _constructPdoDsn(array $params)
|
||||
{
|
||||
$dsn = 'sqlite:';
|
||||
if (isset($params['path'])) {
|
||||
$dsn .= $params['path'];
|
||||
} else if (isset($params['memory'])) {
|
||||
$dsn .= ':memory:';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database platform that is relevant for this driver.
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new \Doctrine\DBAL\Platforms\SqlitePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the schema manager that is relevant for this driver.
|
||||
*
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return Doctrine\DBAL\Schema\SqliteSchemaManager
|
||||
*/
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new \Doctrine\DBAL\Schema\SqliteSchemaManager($conn);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'pdo_sqlite';
|
||||
}
|
||||
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
return isset($params['path']) ? $params['path'] : null;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Interface.php 3882 2008-02-22 18:11:35Z jwage $
|
||||
*
|
||||
* 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\Driver;
|
||||
|
||||
/**
|
||||
* The PDO implementation of the Statement interface.
|
||||
* Used by all PDO-based drivers.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class PDOStatement extends \PDOStatement implements Statement
|
||||
{
|
||||
private function __construct() {}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
<?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\Driver;
|
||||
|
||||
use \PDO;
|
||||
|
||||
/**
|
||||
* Statement interface.
|
||||
* Drivers must implement this interface.
|
||||
*
|
||||
* This resembles (a subset of) the PDOStatement interface.
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
interface Statement
|
||||
{
|
||||
/**
|
||||
* Binds a value to a corresponding named or positional
|
||||
* placeholder in the SQL statement that was used to prepare the statement.
|
||||
*
|
||||
* @param mixed $param Parameter identifier. For a prepared statement using named placeholders,
|
||||
* this will be a parameter name of the form :name. For a prepared statement
|
||||
* using question mark placeholders, this will be the 1-indexed position of the parameter
|
||||
*
|
||||
* @param mixed $value The value to bind to the parameter.
|
||||
* @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function bindValue($param, $value, $type = null);
|
||||
|
||||
/**
|
||||
* Binds a PHP variable to a corresponding named or question mark placeholder in the
|
||||
* SQL statement that was use to prepare the statement. Unlike PDOStatement->bindValue(),
|
||||
* the variable is bound as a reference and will only be evaluated at the time
|
||||
* that PDOStatement->execute() is called.
|
||||
*
|
||||
* Most parameters are input parameters, that is, parameters that are
|
||||
* used in a read-only fashion to build up the query. Some drivers support the invocation
|
||||
* of stored procedures that return data as output parameters, and some also as input/output
|
||||
* parameters that both send in data and are updated to receive it.
|
||||
*
|
||||
* @param mixed $param Parameter identifier. For a prepared statement using named placeholders,
|
||||
* this will be a parameter name of the form :name. For a prepared statement
|
||||
* using question mark placeholders, this will be the 1-indexed position of the parameter
|
||||
*
|
||||
* @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
|
||||
*
|
||||
* @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants. To return
|
||||
* an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
|
||||
* PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function bindParam($column, &$variable, $type = null);
|
||||
|
||||
/**
|
||||
* Closes the cursor, enabling the statement to be executed again.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function closeCursor();
|
||||
|
||||
/**
|
||||
* columnCount
|
||||
* Returns the number of columns in the result set
|
||||
*
|
||||
* @return integer Returns the number of columns in the result set represented
|
||||
* by the PDOStatement object. If there is no result set,
|
||||
* this method should return 0.
|
||||
*/
|
||||
function columnCount();
|
||||
|
||||
/**
|
||||
* errorCode
|
||||
* Fetch the SQLSTATE associated with the last operation on the statement handle
|
||||
*
|
||||
* @see Doctrine_Adapter_Interface::errorCode()
|
||||
* @return string error code string
|
||||
*/
|
||||
function errorCode();
|
||||
|
||||
/**
|
||||
* errorInfo
|
||||
* Fetch extended error information associated with the last operation on the statement handle
|
||||
*
|
||||
* @see Doctrine_Adapter_Interface::errorInfo()
|
||||
* @return array error info array
|
||||
*/
|
||||
function errorInfo();
|
||||
|
||||
/**
|
||||
* Executes a prepared statement
|
||||
*
|
||||
* If the prepared statement included parameter markers, you must either:
|
||||
* call PDOStatement->bindParam() to bind PHP variables to the parameter markers:
|
||||
* bound variables pass their value as input and receive the output value,
|
||||
* if any, of their associated parameter markers or pass an array of input-only
|
||||
* parameter values
|
||||
*
|
||||
*
|
||||
* @param array $params An array of values with as many elements as there are
|
||||
* bound parameters in the SQL statement being executed.
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function execute($params = null);
|
||||
|
||||
/**
|
||||
* fetch
|
||||
*
|
||||
* @see Query::HYDRATE_* constants
|
||||
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_* constants,
|
||||
* defaulting to Query::HYDRATE_BOTH
|
||||
*
|
||||
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
|
||||
* this value determines which row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
|
||||
* Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
|
||||
* PDOStatement object,
|
||||
* you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
|
||||
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
|
||||
*
|
||||
* @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the
|
||||
* $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
|
||||
* the absolute number of the row in the result set that shall be fetched.
|
||||
*
|
||||
* For a PDOStatement object representing a scrollable cursor for
|
||||
* which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
|
||||
* specifies the row to fetch relative to the cursor position before
|
||||
* PDOStatement->fetch() was called.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function fetch($fetchStyle = PDO::FETCH_BOTH);
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the result set rows
|
||||
*
|
||||
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
|
||||
* This value must be one of the Query::HYDRATE_* constants,
|
||||
* defaulting to Query::HYDRATE_BOTH
|
||||
*
|
||||
* @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is
|
||||
* Query::HYDRATE_COLUMN. Defaults to 0.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function fetchAll($fetchStyle = PDO::FETCH_BOTH);
|
||||
|
||||
/**
|
||||
* fetchColumn
|
||||
* Returns a single column from the next row of a
|
||||
* result set or FALSE if there are no more rows.
|
||||
*
|
||||
* @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no
|
||||
* value is supplied, PDOStatement->fetchColumn()
|
||||
* fetches the first column.
|
||||
*
|
||||
* @return string returns a single column in the next row of a result set.
|
||||
*/
|
||||
function fetchColumn($columnIndex = 0);
|
||||
|
||||
/**
|
||||
* rowCount
|
||||
* rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
|
||||
* executed by the corresponding object.
|
||||
*
|
||||
* If the last SQL statement executed by the associated Statement object was a SELECT statement,
|
||||
* some databases may return the number of rows returned by that statement. However,
|
||||
* this behaviour is not guaranteed for all databases and should not be
|
||||
* relied on for portable applications.
|
||||
*
|
||||
* @return integer Returns the number of rows.
|
||||
*/
|
||||
function rowCount();
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* 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;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
|
||||
/**
|
||||
* Factory for creating Doctrine\DBAL\Connection instances.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
final class DriverManager
|
||||
{
|
||||
/**
|
||||
* List of supported drivers and their mappings to the driver classes.
|
||||
*
|
||||
* @var array
|
||||
* @todo REMOVE. Users should directly supply class names instead.
|
||||
*/
|
||||
private static $_driverMap = array(
|
||||
'pdo_mysql' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
|
||||
'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver',
|
||||
'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
|
||||
'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver',
|
||||
'pdo_mssql' => 'Doctrine\DBAL\Driver\PDOMsSql\Driver',
|
||||
'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver',
|
||||
'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver',
|
||||
'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver',
|
||||
);
|
||||
|
||||
/** Private constructor. This class cannot be instantiated. */
|
||||
private function __construct() { }
|
||||
|
||||
/**
|
||||
* Creates a connection object based on the specified parameters.
|
||||
* This method returns a Doctrine\DBAL\Connection which wraps the underlying
|
||||
* driver connection.
|
||||
*
|
||||
* $params must contain at least one of the following.
|
||||
*
|
||||
* Either 'driver' with one of the following values:
|
||||
* pdo_mysql
|
||||
* pdo_sqlite
|
||||
* pdo_pgsql
|
||||
* pdo_oracle
|
||||
* pdo_mssql
|
||||
*
|
||||
* OR 'driverClass' that contains the full class name (with namespace) of the
|
||||
* driver class to instantiate.
|
||||
*
|
||||
* Other (optional) parameters:
|
||||
*
|
||||
* <b>user (string)</b>:
|
||||
* The username to use when connecting.
|
||||
*
|
||||
* <b>password (string)</b>:
|
||||
* The password to use when connecting.
|
||||
*
|
||||
* <b>driverOptions (array)</b>:
|
||||
* Any additional driver-specific options for the driver. These are just passed
|
||||
* through to the driver.
|
||||
*
|
||||
* <b>pdo</b>:
|
||||
* You can pass an existing PDO instance through this parameter. The PDO
|
||||
* instance will be wrapped in a Doctrine\DBAL\Connection.
|
||||
*
|
||||
* <b>wrapperClass</b>:
|
||||
* You may specify a custom wrapper class through the 'wrapperClass'
|
||||
* parameter but this class MUST inherit from Doctrine\DBAL\Connection.
|
||||
*
|
||||
* @param array $params The parameters.
|
||||
* @param Doctrine\DBAL\Configuration The configuration to use.
|
||||
* @param Doctrine\Common\EventManager The event manager to use.
|
||||
* @return Doctrine\DBAL\Connection
|
||||
*/
|
||||
public static function getConnection(
|
||||
array $params,
|
||||
Configuration $config = null,
|
||||
EventManager $eventManager = null)
|
||||
{
|
||||
// create default config and event manager, if not set
|
||||
if ( ! $config) {
|
||||
$config = new Configuration();
|
||||
}
|
||||
if ( ! $eventManager) {
|
||||
$eventManager = new EventManager();
|
||||
}
|
||||
|
||||
// check for existing pdo object
|
||||
if (isset($params['pdo']) && ! $params['pdo'] instanceof \PDO) {
|
||||
throw DBALException::invalidPdoInstance();
|
||||
} else if (isset($params['pdo'])) {
|
||||
$params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
} else {
|
||||
self::_checkParams($params);
|
||||
}
|
||||
if (isset($params['driverClass'])) {
|
||||
$className = $params['driverClass'];
|
||||
} else {
|
||||
$className = self::$_driverMap[$params['driver']];
|
||||
}
|
||||
|
||||
$driver = new $className();
|
||||
|
||||
$wrapperClass = 'Doctrine\DBAL\Connection';
|
||||
if (isset($params['wrapperClass'])) {
|
||||
if (is_subclass_of($params['wrapperClass'], $wrapperClass)) {
|
||||
$wrapperClass = $params['wrapperClass'];
|
||||
} else {
|
||||
throw DBALException::invalidWrapperClass($params['wrapperClass']);
|
||||
}
|
||||
}
|
||||
|
||||
return new $wrapperClass($params, $driver, $config, $eventManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the list of parameters.
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
private static function _checkParams(array $params)
|
||||
{
|
||||
// check existance of mandatory parameters
|
||||
|
||||
// driver
|
||||
if ( ! isset($params['driver']) && ! isset($params['driverClass'])) {
|
||||
throw DBALException::driverRequired();
|
||||
}
|
||||
|
||||
// check validity of parameters
|
||||
|
||||
// driver
|
||||
if ( isset($params['driver']) && ! isset(self::$_driverMap[$params['driver']])) {
|
||||
throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap));
|
||||
}
|
||||
|
||||
if (isset($params['driverClass']) && ! in_array('Doctrine\DBAL\Driver', class_implements($params['driverClass'], true))) {
|
||||
throw DBALException::invalidDriverClass($params['driverClass']);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?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\Event;
|
||||
|
||||
use Doctrine\Common\EventArgs,
|
||||
Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* Event Arguments used when a Driver connection is established inside Doctrine\DBAL\Connection.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class ConnectionEventArgs extends EventArgs
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
private $_connection = null;
|
||||
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->_connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Driver
|
||||
*/
|
||||
public function getDriver()
|
||||
{
|
||||
return $this->_connection->getDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return $this->_connection->getDatabasePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Schema\AbstractSchemaManager
|
||||
*/
|
||||
public function getSchemaManager()
|
||||
{
|
||||
return $this->_connection->getSchemaManager();
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
<?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\Event\Listeners;
|
||||
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
|
||||
/**
|
||||
* MySQL Session Init Event Subscriber which allows to set the Client Encoding of the Connection
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class MysqlSessionInit implements EventSubscriber
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_charset;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_collation;
|
||||
|
||||
/**
|
||||
* Configure Charset and Collation options of MySQL Client for each Connection
|
||||
*
|
||||
* @param string $charset
|
||||
* @param string $collation
|
||||
*/
|
||||
public function __construct($charset = 'utf8', $collation = false)
|
||||
{
|
||||
$this->_charset = $charset;
|
||||
$this->_collation = $collation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConnectionEventArgs $args
|
||||
* @return void
|
||||
*/
|
||||
public function postConnect(ConnectionEventArgs $args)
|
||||
{
|
||||
$collation = ($this->_collation) ? " COLLATE ".$this->_collation : "";
|
||||
$args->getConnection()->executeUpdate("SET NAMES ".$this->_charset . $collation);
|
||||
}
|
||||
|
||||
public function getSubscribedEvents()
|
||||
{
|
||||
return array(Events::postConnect);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
<?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\Event\Listeners;
|
||||
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
|
||||
/**
|
||||
* Should be used when Oracle Server default enviroment does not match the Doctrine requirements.
|
||||
*
|
||||
* The following enviroment variables are required for the Doctrine default date format:
|
||||
*
|
||||
* NLS_TIME_FORMAT="HH24:MI:SS"
|
||||
* NLS_DATE_FORMAT="YYYY-MM-DD"
|
||||
* NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS"
|
||||
* NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS TZH:TZM"
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class OracleSessionInit implements EventSubscriber
|
||||
{
|
||||
protected $_defaultSessionVars = array(
|
||||
'NLS_TIME_FORMAT' => "HH24:MI:SS",
|
||||
'NLS_DATE_FORMAT' => "YYYY-MM-DD",
|
||||
'NLS_TIMESTAMP_FORMAT' => "YYYY-MM-DD HH24:MI:SS",
|
||||
'NLS_TIMESTAMP_TZ_FORMAT' => "YYYY-MM-DD HH24:MI:SS TZH:TZM",
|
||||
);
|
||||
|
||||
/**
|
||||
* @param array $oracleSessionVars
|
||||
*/
|
||||
public function __construct(array $oracleSessionVars = array())
|
||||
{
|
||||
$this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConnectionEventArgs $args
|
||||
* @return void
|
||||
*/
|
||||
public function postConnect(ConnectionEventArgs $args)
|
||||
{
|
||||
if (count($this->_defaultSessionVars)) {
|
||||
array_change_key_case($this->_defaultSessionVars, \CASE_UPPER);
|
||||
$vars = array();
|
||||
foreach ($this->_defaultSessionVars AS $option => $value) {
|
||||
$vars[] = $option." = '".$value."'";
|
||||
}
|
||||
$sql = "ALTER SESSION SET ".implode(" ", $vars);
|
||||
$args->getConnection()->executeUpdate($sql);
|
||||
}
|
||||
}
|
||||
|
||||
public function getSubscribedEvents()
|
||||
{
|
||||
return array(Events::postConnect);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Container for all DBAL events.
|
||||
*
|
||||
* This class cannot be instantiated.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
final class Events
|
||||
{
|
||||
private function __construct() {}
|
||||
|
||||
const preExec = 'preExec';
|
||||
const postExec = 'postExec';
|
||||
const preExecute = 'preExecute';
|
||||
const postExecute = 'postExecute';
|
||||
|
||||
const postConnect = 'postConnect';
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Contains all ORM LockModes
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class LockMode
|
||||
{
|
||||
const NONE = 0;
|
||||
const OPTIMISTIC = 1;
|
||||
const PESSIMISTIC_READ = 2;
|
||||
const PESSIMISTIC_WRITE = 4;
|
||||
|
||||
final private function __construct() { }
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
<?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\Logging;
|
||||
|
||||
/**
|
||||
* Includes executed SQLs in a Debug Stack
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class DebugStack implements SQLLogger
|
||||
{
|
||||
/** @var array $queries Executed SQL queries. */
|
||||
public $queries = array();
|
||||
|
||||
/** @var boolean $enabled If Debug Stack is enabled (log queries) or not. */
|
||||
public $enabled = true;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logSQL($sql, array $params = null)
|
||||
{
|
||||
if ($this->enabled) {
|
||||
$this->queries[] = array('sql' => $sql, 'params' => $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
<?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\Logging;
|
||||
|
||||
/**
|
||||
* A SQL logger that logs to the standard output using echo/var_dump.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class EchoSQLLogger implements SQLLogger
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logSQL($sql, array $params = null)
|
||||
{
|
||||
echo $sql . PHP_EOL;
|
||||
|
||||
if ($params) {
|
||||
var_dump($params);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?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\Logging;
|
||||
|
||||
/**
|
||||
* Interface for SQL loggers.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
interface SQLLogger
|
||||
{
|
||||
/**
|
||||
* Logs a SQL statement somewhere.
|
||||
*
|
||||
* @param string $sql The SQL to be executed.
|
||||
* @param array $params The SQL parameters.
|
||||
*/
|
||||
function logSQL($sql, array $params = null);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,521 +0,0 @@
|
||||
<?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;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
|
||||
class DB2Platform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* Gets the SQL snippet used to declare a VARCHAR column type.
|
||||
*
|
||||
* @param array $field
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet used to declare a CLOB column type.
|
||||
*
|
||||
* @param array $field
|
||||
*/
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
// todo clob(n) with $field['length'];
|
||||
return 'CLOB(1M)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the platform.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'db2';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet that declares a boolean column.
|
||||
*
|
||||
* @param array $columnDef
|
||||
* @return string
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet that declares a 4 byte integer column.
|
||||
*
|
||||
* @param array $columnDef
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet that declares an 8 byte integer column.
|
||||
*
|
||||
* @param array $columnDef
|
||||
* @return string
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet that declares a 2 byte integer column.
|
||||
*
|
||||
* @param array $columnDef
|
||||
* @return string
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet that declares common properties of an integer column.
|
||||
*
|
||||
* @param array $columnDef
|
||||
* @return string
|
||||
*/
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
$autoinc = '';
|
||||
if ( ! empty($columnDef['autoincrement'])) {
|
||||
$autoinc = ' GENERATED BY DEFAULT AS IDENTITY';
|
||||
}
|
||||
return $autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
|
||||
return "TIMESTAMP(0) WITH DEFAULT";
|
||||
}
|
||||
|
||||
return 'TIMESTAMP(0)';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return 'TIME';
|
||||
}
|
||||
|
||||
public function getListDatabasesSQL()
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
public function getListSequencesSQL($database)
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
public function getListTableConstraintsSQL($table)
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
/**
|
||||
* This code fragment is originally from the Zend_Db_Adapter_Db2 class.
|
||||
*
|
||||
* @license New BSD License
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function getListTableColumnsSQL($table)
|
||||
{
|
||||
return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
|
||||
c.typename, c.default, c.nulls, c.length, c.scale,
|
||||
c.identity, tc.type AS tabconsttype, k.colseq
|
||||
FROM syscat.columns c
|
||||
LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
|
||||
ON (k.tabschema = tc.tabschema
|
||||
AND k.tabname = tc.tabname
|
||||
AND tc.type = 'P'))
|
||||
ON (c.tabschema = k.tabschema
|
||||
AND c.tabname = k.tabname
|
||||
AND c.colname = k.colname)
|
||||
WHERE UPPER(c.tabname) = UPPER('" . $table . "') ORDER BY c.colno";
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'";
|
||||
}
|
||||
|
||||
public function getListUsersSQL()
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL to list all views of a database or user.
|
||||
*
|
||||
* @param string $database
|
||||
* @return string
|
||||
*/
|
||||
public function getListViewsSQL($database)
|
||||
{
|
||||
return "SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS";
|
||||
}
|
||||
|
||||
public function getListTableIndexesSQL($table)
|
||||
{
|
||||
return "SELECT NAME, COLNAMES, UNIQUERULE FROM SYSIBM.SYSINDEXES WHERE TBNAME = UPPER('" . $table . "')";
|
||||
}
|
||||
|
||||
public function getListTableForeignKeysSQL($table)
|
||||
{
|
||||
return "SELECT TBNAME, RELNAME, REFTBNAME, DELETERULE, UPDATERULE, FKCOLNAMES, PKCOLNAMES ".
|
||||
"FROM SYSIBM.SYSRELS WHERE TBNAME = UPPER('".$table."')";
|
||||
}
|
||||
|
||||
public function getCreateViewSQL($name, $sql)
|
||||
{
|
||||
return "CREATE VIEW ".$name." AS ".$sql;
|
||||
}
|
||||
|
||||
public function getDropViewSQL($name)
|
||||
{
|
||||
return "DROP VIEW ".$name;
|
||||
}
|
||||
|
||||
public function getDropSequenceSQL($sequence)
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
public function getSequenceNextValSQL($sequenceName)
|
||||
{
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
public function getCreateDatabaseSQL($database)
|
||||
{
|
||||
return "CREATE DATABASE ".$database;
|
||||
}
|
||||
|
||||
public function getDropDatabaseSQL($database)
|
||||
{
|
||||
return "DROP DATABASE ".$database.";";
|
||||
}
|
||||
|
||||
public function supportsCreateDropDatabase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL specific for the platform to get the current date.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentDateSQL()
|
||||
{
|
||||
return 'VALUES CURRENT DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL specific for the platform to get the current time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentTimeSQL()
|
||||
{
|
||||
return 'VALUES CURRENT TIME';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL specific for the platform to get the current timestamp
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
public function getCurrentTimestampSQL()
|
||||
{
|
||||
return "VALUES CURRENT TIMESTAMP";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return $this->getUniqueConstraintDeclarationSQL($name, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @param array $columns
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
|
||||
{
|
||||
$indexes = array();
|
||||
if (isset($options['indexes'])) {
|
||||
$indexes = $options['indexes'];
|
||||
}
|
||||
$options['indexes'] = array();
|
||||
|
||||
$sqls = parent::_getCreateTableSQL($tableName, $columns, $options);
|
||||
|
||||
foreach ($indexes as $index => $definition) {
|
||||
$sqls[] = $this->getCreateIndexSQL($definition, $tableName);
|
||||
}
|
||||
return $sqls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL to alter an existing table.
|
||||
*
|
||||
* @param TableDiff $diff
|
||||
* @return array
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
$queryParts = array();
|
||||
foreach ($diff->addedColumns AS $fieldName => $column) {
|
||||
$queryParts[] = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->removedColumns AS $column) {
|
||||
$queryParts[] = 'DROP COLUMN ' . $column->getName();
|
||||
}
|
||||
|
||||
foreach ($diff->changedColumns AS $columnDiff) {
|
||||
/* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
|
||||
$column = $columnDiff->column;
|
||||
$queryParts[] = 'ALTER ' . ($columnDiff->oldColumnName) . ' '
|
||||
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns AS $oldColumnName => $column) {
|
||||
$queryParts[] = 'RENAME ' . $oldColumnName . ' TO ' . $column->getName();
|
||||
}
|
||||
|
||||
if (count($queryParts) > 0) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(" ", $queryParts);
|
||||
}
|
||||
|
||||
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||
|
||||
if ($diff->newName !== false) {
|
||||
$sql[] = 'RENAME TABLE TO ' . $diff->newName;
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function getDefaultValueDeclarationSQL($field)
|
||||
{
|
||||
if (isset($field['notnull']) && $field['notnull'] && !isset($field['default'])) {
|
||||
if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) {
|
||||
$field['default'] = 0;
|
||||
} else if((string)$field['type'] == "DateTime") {
|
||||
$field['default'] = "00-00-00 00:00:00";
|
||||
} else if ((string)$field['type'] == "Date") {
|
||||
$field['default'] = "00-00-00";
|
||||
} else if((string)$field['type'] == "Time") {
|
||||
$field['default'] = "00:00:00";
|
||||
} else {
|
||||
$field['default'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
unset($field['default']); // @todo this needs fixing
|
||||
if (isset($field['version']) && $field['version']) {
|
||||
if ((string)$field['type'] != "DateTime") {
|
||||
$field['default'] = "1";
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getDefaultValueDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (DEFAULT)';
|
||||
}
|
||||
|
||||
public function getCreateTemporaryTableSnippetSQL()
|
||||
{
|
||||
return "DECLARE GLOBAL TEMPORARY TABLE";
|
||||
}
|
||||
|
||||
/**
|
||||
* DB2 automatically moves temporary tables into the SESSION. schema.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return string
|
||||
*/
|
||||
public function getTemporaryTableName($tableName)
|
||||
{
|
||||
return "SESSION." . $tableName;
|
||||
}
|
||||
|
||||
public function modifyLimitQuery($query, $limit, $offset = null)
|
||||
{
|
||||
if ($limit === null && $offset === null) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
$limit = (int)$limit;
|
||||
$offset = (int)(($offset)?:0);
|
||||
|
||||
// Todo OVER() needs ORDER BY data!
|
||||
$sql = 'SELECT db22.* FROM (SELECT ROW_NUMBER() OVER() AS DC_ROWNUM, db21.* '.
|
||||
'FROM (' . $query . ') db21) db22 WHERE db22.DC_ROWNUM BETWEEN ' . ($offset+1) .' AND ' . ($offset+$limit);
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ')';
|
||||
} else {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $from where to start the substring portion
|
||||
* @param integer $len the substring portion length
|
||||
* @return string
|
||||
*/
|
||||
public function getSubstringExpression($value, $from, $len = null)
|
||||
{
|
||||
if ($len === null)
|
||||
return 'SUBSTR(' . $value . ', ' . $from . ')';
|
||||
else {
|
||||
return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')';
|
||||
}
|
||||
}
|
||||
|
||||
public function supportsIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function prefersIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the character casing of a column in an SQL result set of this platform.
|
||||
*
|
||||
* DB2 returns all column names in SQL result sets in uppercase.
|
||||
*
|
||||
* @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 strtoupper($column);
|
||||
}
|
||||
|
||||
public function getForUpdateSQL()
|
||||
{
|
||||
return ' WITH RR USE AND KEEP UPDATE LOCKS';
|
||||
}
|
||||
}
|
@ -1,514 +0,0 @@
|
||||
<?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\Schema\TableDiff;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
|
||||
/**
|
||||
* The MsSqlPlatform provides the behavior, features and SQL dialect of the
|
||||
* MySQL database platform.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @todo Rename: MsSQLPlatform
|
||||
*/
|
||||
class MsSqlPlatform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* Adds an adapter-specific LIMIT clause to the SELECT statement.
|
||||
* [ borrowed from Zend Framework ]
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed $limit
|
||||
* @param mixed $offset
|
||||
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function writeLimitClause($query, $limit = false, $offset = false)
|
||||
{
|
||||
if ($limit > 0) {
|
||||
$count = intval($limit);
|
||||
|
||||
$offset = intval($offset);
|
||||
if ($offset < 0) {
|
||||
throw DBALException::limitOffsetInvalid($offset);
|
||||
}
|
||||
|
||||
$orderby = stristr($query, 'ORDER BY');
|
||||
if ($orderby !== false) {
|
||||
$sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc';
|
||||
$order = str_ireplace('ORDER BY', '', $orderby);
|
||||
$order = trim(preg_replace('/ASC|DESC/i', '', $order));
|
||||
}
|
||||
|
||||
$query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $query);
|
||||
|
||||
$query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS inner_tbl';
|
||||
if ($orderby !== false) {
|
||||
$query .= ' ORDER BY ' . $order . ' ';
|
||||
$query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
|
||||
}
|
||||
$query .= ') AS outer_tbl';
|
||||
if ($orderby !== false) {
|
||||
$query .= ' ORDER BY ' . $order . ' ' . $sort;
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
$queryParts = array();
|
||||
if ($diff->newName !== false) {
|
||||
$queryParts[] = 'RENAME TO ' . $diff->newName;
|
||||
}
|
||||
|
||||
foreach ($diff->addedColumns AS $fieldName => $column) {
|
||||
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->removedColumns AS $column) {
|
||||
$queryParts[] = 'DROP ' . $column->getName();
|
||||
}
|
||||
|
||||
foreach ($diff->changedColumns AS $columnDiff) {
|
||||
/* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
|
||||
$column = $columnDiff->column;
|
||||
$queryParts[] = 'CHANGE ' . ($columnDiff->oldColumnName) . ' '
|
||||
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns AS $oldColumnName => $column) {
|
||||
$queryParts[] = 'CHANGE ' . $oldColumnName . ' '
|
||||
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
$sql = array();
|
||||
if (count($queryParts) > 0) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(", ", $queryParts);
|
||||
}
|
||||
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regular expression operator.
|
||||
*
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getRegexpExpression()
|
||||
{
|
||||
return 'RLIKE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time:
|
||||
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
|
||||
* - CURRENT_DATE (date, DATE type)
|
||||
* - CURRENT_TIME (time, TIME type)
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @override
|
||||
*/
|
||||
public function getNowExpression($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
case 'date':
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'GETDATE()';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @override
|
||||
*/
|
||||
public function getSubstringExpression($value, $position, $length = null)
|
||||
{
|
||||
if ( ! is_null($length)) {
|
||||
return 'SUBSTRING(' . $value . ', ' . $position . ', ' . $length . ')';
|
||||
}
|
||||
return 'SUBSTRING(' . $value . ', ' . $position . ', LEN(' . $value . ') - ' . $position . ' + 1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
* @param string $arg1
|
||||
* @param string $arg2
|
||||
* @param string $values...
|
||||
* @return string to concatenate two strings
|
||||
* @override
|
||||
*/
|
||||
public function getConcatExpression()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return '(' . implode(' + ', $args) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @override
|
||||
*/
|
||||
public function getGuidExpression()
|
||||
{
|
||||
return 'NEWID()';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform prefers identity columns for ID generation.
|
||||
* MsSql prefers "autoincrement" identity columns since sequences can only
|
||||
* be emulated with a table.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function prefersIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports identity columns.
|
||||
* MsSql supports this through AUTO_INCREMENT columns.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function supportsIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports savepoints. MsSql does not.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function supportsSavepoints()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getShowDatabasesSQL()
|
||||
{
|
||||
return 'SHOW DATABASES';
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return 'SHOW TABLES';
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getCreateDatabaseSQL($name)
|
||||
{
|
||||
return 'CREATE DATABASE ' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getDropDatabaseSQL($name)
|
||||
{
|
||||
return 'DROP DATABASE ' . $name;
|
||||
}
|
||||
|
||||
public function getSetTransactionIsolationSQL($level)
|
||||
{
|
||||
return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
$autoinc = '';
|
||||
if ( ! empty($columnDef['autoincrement'])) {
|
||||
$autoinc = ' AUTO_INCREMENT';
|
||||
}
|
||||
$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
|
||||
|
||||
return $unsigned . $autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'CHAR(' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'CHAR(' . strlen('YYYY-MM-DD') . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'CHAR(' . strlen('HH:MM:SS') . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'BIT';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'mssql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an adapter-specific LIMIT clause to the SELECT statement.
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed $limit
|
||||
* @param mixed $offset
|
||||
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
|
||||
* @return string
|
||||
*/
|
||||
public function modifyLimitQuery($query, $limit, $offset = null)
|
||||
{
|
||||
if ($limit > 0) {
|
||||
$count = intval($limit);
|
||||
$offset = intval($offset);
|
||||
|
||||
if ($offset < 0) {
|
||||
throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
|
||||
}
|
||||
|
||||
$orderby = stristr($query, 'ORDER BY');
|
||||
|
||||
if ($orderby !== false) {
|
||||
// Ticket #1835: Fix for ORDER BY alias
|
||||
// Ticket #2050: Fix for multiple ORDER BY clause
|
||||
$order = str_ireplace('ORDER BY', '', $orderby);
|
||||
$orders = explode(',', $order);
|
||||
|
||||
for ($i = 0; $i < count($orders); $i++) {
|
||||
$sorts[$i] = (stripos($orders[$i], ' DESC') !== false) ? 'DESC' : 'ASC';
|
||||
$orders[$i] = trim(preg_replace('/\s+(ASC|DESC)$/i', '', $orders[$i]));
|
||||
|
||||
// find alias in query string
|
||||
$helperString = stristr($query, $orders[$i]);
|
||||
|
||||
$fromClausePos = strpos($helperString, ' FROM ');
|
||||
$fieldsString = substr($helperString, 0, $fromClausePos + 1);
|
||||
|
||||
$fieldArray = explode(',', $fieldsString);
|
||||
$fieldArray = array_shift($fieldArray);
|
||||
$aux2 = preg_split('/ as /i', $fieldArray);
|
||||
|
||||
$aliases[$i] = trim(end($aux2));
|
||||
}
|
||||
}
|
||||
|
||||
// Ticket #1259: Fix for limit-subquery in MSSQL
|
||||
$selectRegExp = 'SELECT\s+';
|
||||
$selectReplace = 'SELECT ';
|
||||
|
||||
if (preg_match('/^SELECT(\s+)DISTINCT/i', $query)) {
|
||||
$selectRegExp .= 'DISTINCT\s+';
|
||||
$selectReplace .= 'DISTINCT ';
|
||||
}
|
||||
|
||||
$query = preg_replace('/^'.$selectRegExp.'/i', $selectReplace . 'TOP ' . ($count + $offset) . ' ', $query);
|
||||
$query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS ' . 'inner_tbl';
|
||||
|
||||
if ($orderby !== false) {
|
||||
$query .= ' ORDER BY ';
|
||||
|
||||
for ($i = 0, $l = count($orders); $i < $l; $i++) {
|
||||
if ($i > 0) { // not first order clause
|
||||
$query .= ', ';
|
||||
}
|
||||
|
||||
$query .= 'inner_tbl' . '.' . $aliases[$i] . ' ';
|
||||
$query .= (stripos($sorts[$i], 'ASC') !== false) ? 'DESC' : 'ASC';
|
||||
}
|
||||
}
|
||||
|
||||
$query .= ') AS ' . 'outer_tbl';
|
||||
|
||||
if ($orderby !== false) {
|
||||
$query .= ' ORDER BY ';
|
||||
|
||||
for ($i = 0, $l = count($orders); $i < $l; $i++) {
|
||||
if ($i > 0) { // not first order clause
|
||||
$query .= ', ';
|
||||
}
|
||||
|
||||
$query .= 'outer_tbl' . '.' . $aliases[$i] . ' ' . $sorts[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the insert sql for an empty insert statement
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $identifierColumnName
|
||||
* @return string $sql
|
||||
*/
|
||||
public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
|
||||
{
|
||||
return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTruncateTableSQL($tableName, $cascade = false)
|
||||
{
|
||||
return 'TRUNCATE TABLE '.$tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* MsSql uses Table Hints for locking strategies instead of the ANSI SQL FOR UPDATE like hints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getForUpdateSQL()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @license LGPL
|
||||
* @author Hibernate
|
||||
* @param string $fromClause
|
||||
* @param int $lockMode
|
||||
* @return string
|
||||
*/
|
||||
public function appendLockHint($fromClause, $lockMode)
|
||||
{
|
||||
if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) {
|
||||
return $fromClause . " WITH (UPDLOCK, ROWLOCK)";
|
||||
} else if ( $lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ ) {
|
||||
return $fromClause . " WITH (HOLDLOCK, ROWLOCK)";
|
||||
} else {
|
||||
return $fromClause;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,591 +0,0 @@
|
||||
<?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\Schema\TableDiff;
|
||||
|
||||
/**
|
||||
* The MySqlPlatform provides the behavior, features and SQL dialect of the
|
||||
* MySQL database platform. This platform represents a MySQL 5.0 or greater platform that
|
||||
* uses the InnoDB storage engine.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @todo Rename: MySQLPlatform
|
||||
*/
|
||||
class MySqlPlatform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* Gets the character used for identifier quoting.
|
||||
*
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getIdentifierQuoteCharacter()
|
||||
{
|
||||
return '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regular expression operator.
|
||||
*
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getRegexpExpression()
|
||||
{
|
||||
return 'RLIKE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @override
|
||||
*/
|
||||
public function getGuidExpression()
|
||||
{
|
||||
return 'UUID()';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ')';
|
||||
} else {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a series of strings concatinated
|
||||
*
|
||||
* concat() accepts an arbitrary number of parameters. Each parameter
|
||||
* must contain an expression or an array with expressions.
|
||||
*
|
||||
* @param string|array(string) strings that will be concatinated.
|
||||
* @override
|
||||
*/
|
||||
public function getConcatExpression()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return 'CONCAT(' . join(', ', (array) $args) . ')';
|
||||
}
|
||||
|
||||
public function getListDatabasesSQL()
|
||||
{
|
||||
return 'SHOW DATABASES';
|
||||
}
|
||||
|
||||
public function getListTableConstraintsSQL($table)
|
||||
{
|
||||
return 'SHOW INDEX FROM ' . $table;
|
||||
}
|
||||
|
||||
public function getListTableIndexesSQL($table)
|
||||
{
|
||||
return 'SHOW INDEX FROM ' . $table;
|
||||
}
|
||||
|
||||
public function getListViewsSQL($database)
|
||||
{
|
||||
return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'";
|
||||
}
|
||||
|
||||
public function getListTableForeignKeysSQL($table, $database = null)
|
||||
{
|
||||
$sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ".
|
||||
"k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ".
|
||||
"FROM information_schema.key_column_usage k /*!50116 ".
|
||||
"INNER JOIN information_schema.referential_constraints c ON k.`CONSTRAINT_NAME` = c.constraint_name AND ".
|
||||
" c.constraint_name = k.constraint_name AND ".
|
||||
" c.table_name = '$table' */ WHERE k.table_name = '$table'";
|
||||
|
||||
if ( ! is_null($database)) {
|
||||
$sql .= " AND table_schema = '$database'";
|
||||
}
|
||||
|
||||
$sql .= " AND `REFERENCED_COLUMN_NAME` is not NULL";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function getCreateViewSQL($name, $sql)
|
||||
{
|
||||
return 'CREATE VIEW ' . $name . ' AS ' . $sql;
|
||||
}
|
||||
|
||||
public function getDropViewSQL($name)
|
||||
{
|
||||
return 'DROP VIEW '. $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
|
||||
*
|
||||
* @params array $field
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYTEXT';
|
||||
} else if ($length <= 65532) {
|
||||
return 'TEXT';
|
||||
} else if ($length <= 16777215) {
|
||||
return 'MEDIUMTEXT';
|
||||
}
|
||||
}
|
||||
return 'LONGTEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
|
||||
return 'TIMESTAMP';
|
||||
} else {
|
||||
return 'DATETIME';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIME';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'TINYINT(1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 getCollationFieldDeclaration($collation)
|
||||
{
|
||||
return 'COLLATE ' . $collation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform prefers identity columns for ID generation.
|
||||
* MySql prefers "autoincrement" identity columns since sequences can only
|
||||
* be emulated with a table.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function prefersIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports identity columns.
|
||||
* MySql supports this through AUTO_INCREMENT columns.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function supportsIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports savepoints. MySql does not.
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function supportsSavepoints()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getShowDatabasesSQL()
|
||||
{
|
||||
return 'SHOW DATABASES';
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return 'SHOW FULL TABLES WHERE Table_type = "BASE TABLE"';
|
||||
}
|
||||
|
||||
public function getListTableColumnsSQL($table)
|
||||
{
|
||||
return 'DESCRIBE ' . $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getCreateDatabaseSQL($name)
|
||||
{
|
||||
return 'CREATE DATABASE ' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getDropDatabaseSQL($name)
|
||||
{
|
||||
return 'DROP DATABASE ' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $tableName Name of the database that should be created
|
||||
* @param array $columns Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
* array(
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @param array $options An associative array of table options:
|
||||
* array(
|
||||
* 'comment' => 'Foo',
|
||||
* 'charset' => 'utf8',
|
||||
* 'collate' => 'utf8_unicode_ci',
|
||||
* 'type' => 'innodb',
|
||||
* );
|
||||
*
|
||||
* @return void
|
||||
* @override
|
||||
*/
|
||||
protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
|
||||
{
|
||||
$queryFields = $this->getColumnDeclarationListSQL($columns);
|
||||
|
||||
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
|
||||
foreach ($options['uniqueConstraints'] as $index => $definition) {
|
||||
$queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
// add all indexes
|
||||
if (isset($options['indexes']) && ! empty($options['indexes'])) {
|
||||
foreach($options['indexes'] as $index => $definition) {
|
||||
$queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
// attach all primary keys
|
||||
if (isset($options['primary']) && ! empty($options['primary'])) {
|
||||
$keyColumns = array_unique(array_values($options['primary']));
|
||||
$queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
|
||||
}
|
||||
|
||||
$query = 'CREATE ';
|
||||
if (!empty($options['temporary'])) {
|
||||
$query .= 'TEMPORARY ';
|
||||
}
|
||||
$query.= 'TABLE ' . $tableName . ' (' . $queryFields . ')';
|
||||
|
||||
$optionStrings = array();
|
||||
|
||||
if (isset($options['comment'])) {
|
||||
$optionStrings['comment'] = 'COMMENT = ' . $this->quote($options['comment'], 'text');
|
||||
}
|
||||
if (isset($options['charset'])) {
|
||||
$optionStrings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset'];
|
||||
if (isset($options['collate'])) {
|
||||
$optionStrings['charset'] .= ' COLLATE ' . $options['collate'];
|
||||
}
|
||||
}
|
||||
|
||||
// get the type of the table
|
||||
if (isset($options['engine'])) {
|
||||
$optionStrings[] = 'ENGINE = ' . $engine;
|
||||
} else {
|
||||
// default to innodb
|
||||
$optionStrings[] = 'ENGINE = InnoDB';
|
||||
}
|
||||
|
||||
if ( ! empty($optionStrings)) {
|
||||
$query.= ' '.implode(' ', $optionStrings);
|
||||
}
|
||||
$sql[] = $query;
|
||||
|
||||
if (isset($options['foreignKeys'])) {
|
||||
foreach ((array) $options['foreignKeys'] as $definition) {
|
||||
$sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL to alter an existing table.
|
||||
*
|
||||
* @param TableDiff $diff
|
||||
* @return array
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$queryParts = array();
|
||||
if ($diff->newName !== false) {
|
||||
$queryParts[] = 'RENAME TO ' . $diff->newName;
|
||||
}
|
||||
|
||||
foreach ($diff->addedColumns AS $fieldName => $column) {
|
||||
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->removedColumns AS $column) {
|
||||
$queryParts[] = 'DROP ' . $column->getName();
|
||||
}
|
||||
|
||||
foreach ($diff->changedColumns AS $columnDiff) {
|
||||
/* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
|
||||
$column = $columnDiff->column;
|
||||
$queryParts[] = 'CHANGE ' . ($columnDiff->oldColumnName) . ' '
|
||||
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns AS $oldColumnName => $column) {
|
||||
$queryParts[] = 'CHANGE ' . $oldColumnName . ' '
|
||||
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
|
||||
$sql = array();
|
||||
if (count($queryParts) > 0) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(", ", $queryParts);
|
||||
}
|
||||
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $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:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer 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.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @override
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
$autoinc = '';
|
||||
if ( ! empty($columnDef['autoincrement'])) {
|
||||
$autoinc = ' AUTO_INCREMENT';
|
||||
}
|
||||
$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
|
||||
|
||||
return $unsigned . $autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FOREIGN KEY query section dealing with non-standard options
|
||||
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
|
||||
*
|
||||
* @param ForeignKeyConstraint $foreignKey
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
|
||||
{
|
||||
$query = '';
|
||||
if ($foreignKey->hasOption('match')) {
|
||||
$query .= ' MATCH ' . $foreignKey->getOption('match');
|
||||
}
|
||||
$query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL to drop an index of a table.
|
||||
*
|
||||
* @param Index $index name of the index to be dropped
|
||||
* @param string|Table $table name of table that should be used in method
|
||||
* @override
|
||||
*/
|
||||
public function getDropIndexSQL($index, $table=null)
|
||||
{
|
||||
if($index instanceof \Doctrine\DBAL\Schema\Index) {
|
||||
$index = $index->getName();
|
||||
} else if(!is_string($index)) {
|
||||
throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
|
||||
}
|
||||
|
||||
if($table instanceof \Doctrine\DBAL\Schema\Table) {
|
||||
$table = $table->getName();
|
||||
} else if(!is_string($table)) {
|
||||
throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
|
||||
}
|
||||
|
||||
return 'DROP INDEX ' . $index . ' ON ' . $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL to drop a table.
|
||||
*
|
||||
* @param string $table The name of table to drop.
|
||||
* @override
|
||||
*/
|
||||
public function getDropTableSQL($table)
|
||||
{
|
||||
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
|
||||
$table = $table->getName();
|
||||
} else if(!is_string($table)) {
|
||||
throw new \InvalidArgumentException('MysqlPlatform::getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
|
||||
}
|
||||
|
||||
return 'DROP TABLE ' . $table;
|
||||
}
|
||||
|
||||
public function getSetTransactionIsolationSQL($level)
|
||||
{
|
||||
return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'mysql';
|
||||
}
|
||||
|
||||
public function createsExplicitIndexForForeignKeys()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getReadLockSQL()
|
||||
{
|
||||
return 'LOCK IN SHARE MODE';
|
||||
}
|
||||
}
|
@ -1,653 +0,0 @@
|
||||
<?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\Schema\TableDiff;
|
||||
|
||||
/**
|
||||
* OraclePlatform.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class OraclePlatform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* Note: Not SQL92, but common functionality.
|
||||
*
|
||||
* @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
|
||||
* @override
|
||||
*/
|
||||
public function getSubstringExpression($value, $position, $length = null)
|
||||
{
|
||||
if ($length !== null) {
|
||||
return "SUBSTR($value, $position, $length)";
|
||||
}
|
||||
|
||||
return "SUBSTR($value, $position)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time:
|
||||
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
|
||||
* - CURRENT_DATE (date, DATE type)
|
||||
* - CURRENT_TIME (time, TIME type)
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @override
|
||||
*/
|
||||
public function getNowExpression($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'INSTR('.$str.', '.$substr.')';
|
||||
} else {
|
||||
return 'INSTR('.$str.', '.$substr.', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @override
|
||||
*/
|
||||
public function getGuidExpression()
|
||||
{
|
||||
return 'SYS_GUID()';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL used to create a sequence that starts with a given value
|
||||
* and increments by the given allocation size.
|
||||
*
|
||||
* Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH.
|
||||
* Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection
|
||||
* in {@see listSequences()}
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Sequence $sequence
|
||||
* @return string
|
||||
*/
|
||||
public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
|
||||
{
|
||||
return 'CREATE SEQUENCE ' . $sequence->getName() .
|
||||
' START WITH ' . $sequence->getInitialValue() .
|
||||
' MINVALUE ' . $sequence->getInitialValue() .
|
||||
' INCREMENT BY ' . $sequence->getAllocationSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $sequenceName
|
||||
* @override
|
||||
*/
|
||||
public function getSequenceNextValSQL($sequenceName)
|
||||
{
|
||||
return 'SELECT ' . $sequenceName . '.nextval FROM DUAL';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param integer $level
|
||||
* @override
|
||||
*/
|
||||
public function getSetTransactionIsolationSQL($level)
|
||||
{
|
||||
return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
|
||||
protected function _getTransactionIsolationLevelSQL($level)
|
||||
{
|
||||
switch ($level) {
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED:
|
||||
return 'READ UNCOMMITTED';
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED:
|
||||
return 'READ COMMITTED';
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ:
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE:
|
||||
return 'SERIALIZABLE';
|
||||
default:
|
||||
return parent::_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'NUMBER(1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'NUMBER(10)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'NUMBER(20)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'NUMBER(5)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIMESTAMP(0) WITH TIME ZONE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet used to declare a VARCHAR column on the Oracle platform.
|
||||
*
|
||||
* @params array $field
|
||||
* @override
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)')
|
||||
: ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)');
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'CLOB';
|
||||
}
|
||||
|
||||
public function getListDatabasesSQL()
|
||||
{
|
||||
return 'SELECT username FROM all_users';
|
||||
}
|
||||
|
||||
public function getListSequencesSQL($database)
|
||||
{
|
||||
return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ".
|
||||
"WHERE SEQUENCE_OWNER = '".strtoupper($database)."'";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $table
|
||||
* @param array $columns
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
protected function _getCreateTableSQL($table, array $columns, array $options = array())
|
||||
{
|
||||
$indexes = isset($options['indexes']) ? $options['indexes'] : array();
|
||||
$options['indexes'] = array();
|
||||
$sql = parent::_getCreateTableSQL($table, $columns, $options);
|
||||
|
||||
foreach ($columns as $name => $column) {
|
||||
if (isset($column['sequence'])) {
|
||||
$sql[] = $this->getCreateSequenceSQL($column['sequence'], 1);
|
||||
}
|
||||
|
||||
if (isset($column['autoincrement']) && $column['autoincrement'] ||
|
||||
(isset($column['autoinc']) && $column['autoinc'])) {
|
||||
$sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($indexes) && ! empty($indexes)) {
|
||||
foreach ($indexes as $indexName => $index) {
|
||||
$sql[] = $this->getCreateIndexSQL($index, $table);
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @license New BSD License
|
||||
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function getListTableIndexesSQL($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
|
||||
return "SELECT uind.index_name AS name, " .
|
||||
" uind.index_type AS type, " .
|
||||
" decode( uind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1 ) AS is_unique, " .
|
||||
" uind_col.column_name AS column_name, " .
|
||||
" uind_col.column_position AS column_pos, " .
|
||||
" (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ".
|
||||
"FROM user_indexes uind, user_ind_columns uind_col " .
|
||||
"WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '$table' ORDER BY uind_col.column_position ASC";
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return 'SELECT * FROM sys.user_tables';
|
||||
}
|
||||
|
||||
public function getListViewsSQL($database)
|
||||
{
|
||||
return 'SELECT view_name, text FROM sys.user_views';
|
||||
}
|
||||
|
||||
public function getCreateViewSQL($name, $sql)
|
||||
{
|
||||
return 'CREATE VIEW ' . $name . ' AS ' . $sql;
|
||||
}
|
||||
|
||||
public function getDropViewSQL($name)
|
||||
{
|
||||
return 'DROP VIEW '. $name;
|
||||
}
|
||||
|
||||
public function getCreateAutoincrementSql($name, $table, $start = 1)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
$sql = array();
|
||||
|
||||
$indexName = $table . '_AI_PK';
|
||||
$definition = array(
|
||||
'primary' => true,
|
||||
'columns' => array($name => true),
|
||||
);
|
||||
|
||||
$idx = new \Doctrine\DBAL\Schema\Index($indexName, array($name), true, true);
|
||||
|
||||
$sql[] = 'DECLARE
|
||||
constraints_Count NUMBER;
|
||||
BEGIN
|
||||
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\';
|
||||
IF constraints_Count = 0 OR constraints_Count = \'\' THEN
|
||||
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $table).'\';
|
||||
END IF;
|
||||
END;';
|
||||
|
||||
$sequenceName = $table . '_SEQ';
|
||||
$sequence = new \Doctrine\DBAL\Schema\Sequence($sequenceName, $start);
|
||||
$sql[] = $this->getCreateSequenceSQL($sequence);
|
||||
|
||||
$triggerName = $table . '_AI_PK';
|
||||
$sql[] = 'CREATE TRIGGER ' . $triggerName . '
|
||||
BEFORE INSERT
|
||||
ON ' . $table . '
|
||||
FOR EACH ROW
|
||||
DECLARE
|
||||
last_Sequence NUMBER;
|
||||
last_InsertID NUMBER;
|
||||
BEGIN
|
||||
SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
|
||||
IF (:NEW.' . $name . ' IS NULL OR :NEW.'.$name.' = 0) THEN
|
||||
SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
|
||||
ELSE
|
||||
SELECT NVL(Last_Number, 0) INTO last_Sequence
|
||||
FROM User_Sequences
|
||||
WHERE Sequence_Name = \'' . $sequenceName . '\';
|
||||
SELECT :NEW.' . $name . ' INTO last_InsertID FROM DUAL;
|
||||
WHILE (last_InsertID > last_Sequence) LOOP
|
||||
SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
|
||||
END LOOP;
|
||||
END IF;
|
||||
END;';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function getDropAutoincrementSql($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
$trigger = $table . '_AI_PK';
|
||||
|
||||
if ($trigger) {
|
||||
$sql[] = 'DROP TRIGGER ' . $trigger;
|
||||
$sql[] = $this->getDropSequenceSQL($table.'_SEQ');
|
||||
|
||||
$indexName = $table . '_AI_PK';
|
||||
$sql[] = $this->getDropConstraintSQL($indexName, $table);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function getListTableForeignKeysSQL($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
|
||||
return "SELECT alc.constraint_name,
|
||||
alc.DELETE_RULE,
|
||||
alc.search_condition,
|
||||
cols.column_name \"local_column\",
|
||||
cols.position,
|
||||
r_alc.table_name \"references_table\",
|
||||
r_cols.column_name \"foreign_column\"
|
||||
FROM all_cons_columns cols
|
||||
LEFT JOIN all_constraints alc
|
||||
ON alc.constraint_name = cols.constraint_name
|
||||
AND alc.owner = cols.owner
|
||||
LEFT JOIN all_constraints r_alc
|
||||
ON alc.r_constraint_name = r_alc.constraint_name
|
||||
AND alc.r_owner = r_alc.owner
|
||||
LEFT JOIN all_cons_columns r_cols
|
||||
ON r_alc.constraint_name = r_cols.constraint_name
|
||||
AND r_alc.owner = r_cols.owner
|
||||
AND cols.position = r_cols.position
|
||||
WHERE alc.constraint_name = cols.constraint_name
|
||||
AND alc.constraint_type = 'R'
|
||||
AND alc.table_name = '".$table."'";
|
||||
}
|
||||
|
||||
public function getListTableConstraintsSQL($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
return 'SELECT * FROM user_constraints WHERE table_name = \'' . $table . '\'';
|
||||
}
|
||||
|
||||
public function getListTableColumnsSQL($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
return "SELECT * FROM all_tab_columns WHERE table_name = '" . $table . "' ORDER BY column_name";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Sequence $sequence
|
||||
* @return string
|
||||
*/
|
||||
public function getDropSequenceSQL($sequence)
|
||||
{
|
||||
if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
|
||||
$sequence = $sequence->getName();
|
||||
}
|
||||
|
||||
return 'DROP SEQUENCE ' . $sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 CONSTRAINT ' . $foreignKey;
|
||||
}
|
||||
|
||||
public function getDropDatabaseSQL($database)
|
||||
{
|
||||
return 'DROP USER ' . $database . ' CASCADE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sql statements for altering an existing table.
|
||||
*
|
||||
* The method returns an array of sql statements, since some platforms need several statements.
|
||||
*
|
||||
* @param string $diff->name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type *
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @return array
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
$fields = array();
|
||||
foreach ($diff->addedColumns AS $column) {
|
||||
$fields[] = $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
}
|
||||
if (count($fields)) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ADD (' . implode(', ', $fields) . ')';
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
foreach ($diff->changedColumns AS $columnDiff) {
|
||||
$column = $columnDiff->column;
|
||||
$fields[] = $column->getName(). ' ' . $this->getColumnDeclarationSQL('', $column->toArray());
|
||||
}
|
||||
if (count($fields)) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' MODIFY (' . implode(', ', $fields) . ')';
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns AS $oldColumnName => $column) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName .' TO ' . $column->getName();
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
foreach ($diff->removedColumns AS $column) {
|
||||
$fields[] = $column->getName();
|
||||
}
|
||||
if (count($fields)) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' DROP COLUMN ' . implode(', ', $fields);
|
||||
}
|
||||
|
||||
if ($diff->newName !== false) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
|
||||
}
|
||||
|
||||
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform prefers sequences for ID generation.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function prefersSequences()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'oracle';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an driver-specific LIMIT clause to the query
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @param integer $limit limit the number of rows
|
||||
* @param integer $offset start reading from given offset
|
||||
* @return string the modified query
|
||||
*/
|
||||
public function modifyLimitQuery($query, $limit, $offset = null)
|
||||
{
|
||||
$limit = (int) $limit;
|
||||
$offset = (int) $offset;
|
||||
if (preg_match('/^\s*SELECT/i', $query)) {
|
||||
if ( ! preg_match('/\sFROM\s/i', $query)) {
|
||||
$query .= " FROM dual";
|
||||
}
|
||||
if ($limit > 0) {
|
||||
$max = $offset + $limit;
|
||||
$column = '*';
|
||||
if ($offset > 0) {
|
||||
$min = $offset + 1;
|
||||
$query = 'SELECT b.'.$column.' FROM ('.
|
||||
'SELECT a.*, ROWNUM AS doctrine_rownum FROM ('
|
||||
. $query . ') a '.
|
||||
') b '.
|
||||
'WHERE doctrine_rownum BETWEEN ' . $min . ' AND ' . $max;
|
||||
} else {
|
||||
$query = 'SELECT a.'.$column.' FROM (' . $query .') a WHERE ROWNUM <= ' . $max;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the character casing of a column in an SQL result set of this platform.
|
||||
*
|
||||
* Oracle returns all column names in SQL result sets in uppercase.
|
||||
*
|
||||
* @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 strtoupper($column);
|
||||
}
|
||||
|
||||
public function getCreateTemporaryTableSnippetSQL()
|
||||
{
|
||||
return "CREATE GLOBAL TEMPORARY TABLE";
|
||||
}
|
||||
|
||||
public function getDateTimeFormatString()
|
||||
{
|
||||
return 'Y-m-d H:i:sP';
|
||||
}
|
||||
|
||||
public function fixSchemaElementName($schemaElementName)
|
||||
{
|
||||
if (strlen($schemaElementName) > 30) {
|
||||
// Trim it
|
||||
return substr($schemaElementName, 0, 30);
|
||||
}
|
||||
return $schemaElementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum length of any given databse identifier, like tables or column names.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxIdentifierLength()
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports sequences.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsSequences()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function supportsForeignKeyOnUpdate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTruncateTableSQL($tableName, $cascade = false)
|
||||
{
|
||||
return 'TRUNCATE TABLE '.$tableName;
|
||||
}
|
||||
}
|
@ -1,645 +0,0 @@
|
||||
<?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\Schema\TableDiff,
|
||||
Doctrine\DBAL\Schema\Table;
|
||||
|
||||
/**
|
||||
* PostgreSqlPlatform.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @todo Rename: PostgreSQLPlatform
|
||||
*/
|
||||
class PostgreSqlPlatform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* Returns part of a string.
|
||||
*
|
||||
* Note: Not SQL92, but common functionality.
|
||||
*
|
||||
* @param string $value the target $value the string or the string column.
|
||||
* @param int $from extract from this characeter.
|
||||
* @param int $len extract this amount of characters.
|
||||
* @return string sql that extracts part of a string.
|
||||
* @override
|
||||
*/
|
||||
public function getSubstringExpression($value, $from, $len = null)
|
||||
{
|
||||
if ($len === null) {
|
||||
return 'SUBSTR(' . $value . ', ' . $from . ')';
|
||||
} else {
|
||||
return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SQL string to return the current system date and time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNowExpression()
|
||||
{
|
||||
return 'LOCALTIMESTAMP(0)';
|
||||
}
|
||||
|
||||
/**
|
||||
* regexp
|
||||
*
|
||||
* @return string the regular expression operator
|
||||
* @override
|
||||
*/
|
||||
public function getRegexpExpression()
|
||||
{
|
||||
return 'SIMILAR TO';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos !== false) {
|
||||
$str = $this->getSubstringExpression($str, $startPos);
|
||||
return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END';
|
||||
} else {
|
||||
return 'POSITION('.$substr.' IN '.$str.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a literal boolean value and returns
|
||||
* proper sql equivalent
|
||||
*
|
||||
* @param string $value boolean value to be parsed
|
||||
* @return string parsed boolean value
|
||||
*/
|
||||
/*public function parseBoolean($value)
|
||||
{
|
||||
return $value;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Whether the platform supports sequences.
|
||||
* Postgres has native support for sequences.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsSequences()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports database schemas.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsSchemas()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform supports identity columns.
|
||||
* Postgres supports these through the SERIAL keyword.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the platform prefers sequences for ID generation.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function prefersSequences()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getListDatabasesSQL()
|
||||
{
|
||||
return 'SELECT datname FROM pg_database';
|
||||
}
|
||||
|
||||
public function getListSequencesSQL($database)
|
||||
{
|
||||
return "SELECT
|
||||
relname
|
||||
FROM
|
||||
pg_class
|
||||
WHERE relkind = 'S' AND relnamespace IN
|
||||
(SELECT oid FROM pg_namespace
|
||||
WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return "SELECT
|
||||
c.relname AS table_name
|
||||
FROM pg_class c, pg_user u
|
||||
WHERE c.relowner = u.usesysid
|
||||
AND c.relkind = 'r'
|
||||
AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
|
||||
AND c.relname !~ '^(pg_|sql_)'
|
||||
UNION
|
||||
SELECT c.relname AS table_name
|
||||
FROM pg_class c
|
||||
WHERE c.relkind = 'r'
|
||||
AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
|
||||
AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner)
|
||||
AND c.relname !~ '^pg_'";
|
||||
}
|
||||
|
||||
public function getListViewsSQL($database)
|
||||
{
|
||||
return 'SELECT viewname, definition FROM pg_views';
|
||||
}
|
||||
|
||||
public function getListTableForeignKeysSQL($table, $database = null)
|
||||
{
|
||||
return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
|
||||
FROM pg_catalog.pg_constraint r
|
||||
WHERE r.conrelid =
|
||||
(
|
||||
SELECT c.oid
|
||||
FROM pg_catalog.pg_class c
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE c.relname = '" . $table . "' AND pg_catalog.pg_table_is_visible(c.oid)
|
||||
)
|
||||
AND r.contype = 'f'";
|
||||
}
|
||||
|
||||
public function getCreateViewSQL($name, $sql)
|
||||
{
|
||||
return 'CREATE VIEW ' . $name . ' AS ' . $sql;
|
||||
}
|
||||
|
||||
public function getDropViewSQL($name)
|
||||
{
|
||||
return 'DROP VIEW '. $name;
|
||||
}
|
||||
|
||||
public function getListTableConstraintsSQL($table)
|
||||
{
|
||||
return "SELECT
|
||||
relname
|
||||
FROM
|
||||
pg_class
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.relname = '$table'
|
||||
AND pg_class.oid = pg_index.indrelid
|
||||
AND (indisunique = 't' OR indisprimary = 't')
|
||||
)";
|
||||
}
|
||||
|
||||
/**
|
||||
* @license New BSD License
|
||||
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function getListTableIndexesSQL($table)
|
||||
{
|
||||
return "SELECT relname, pg_index.indisunique, pg_index.indisprimary,
|
||||
pg_index.indkey, pg_index.indrelid
|
||||
FROM pg_class, pg_index
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.relname='$table' AND pg_class.oid=pg_index.indrelid
|
||||
) AND pg_index.indexrelid = oid";
|
||||
}
|
||||
|
||||
public function getListTableColumnsSQL($table)
|
||||
{
|
||||
return "SELECT
|
||||
a.attnum,
|
||||
a.attname AS field,
|
||||
t.typname AS type,
|
||||
format_type(a.atttypid, a.atttypmod) AS complete_type,
|
||||
a.attnotnull AS isnotnull,
|
||||
(SELECT 't'
|
||||
FROM pg_index
|
||||
WHERE c.oid = pg_index.indrelid
|
||||
AND pg_index.indkey[0] = a.attnum
|
||||
AND pg_index.indisprimary = 't'
|
||||
) AS pri,
|
||||
(SELECT pg_attrdef.adsrc
|
||||
FROM pg_attrdef
|
||||
WHERE c.oid = pg_attrdef.adrelid
|
||||
AND pg_attrdef.adnum=a.attnum
|
||||
) AS default
|
||||
FROM pg_attribute a, pg_class c, pg_type t
|
||||
WHERE c.relname = '$table'
|
||||
AND a.attnum > 0
|
||||
AND a.attrelid = c.oid
|
||||
AND a.atttypid = t.oid
|
||||
ORDER BY a.attnum";
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @throws PDOException
|
||||
* @return void
|
||||
* @override
|
||||
*/
|
||||
public function getCreateDatabaseSQL($name)
|
||||
{
|
||||
return 'CREATE DATABASE ' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @throws PDOException
|
||||
* @access public
|
||||
*/
|
||||
public function getDropDatabaseSQL($name)
|
||||
{
|
||||
return 'DROP DATABASE ' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FOREIGN KEY query section dealing with non-standard options
|
||||
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey foreign key definition
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
|
||||
{
|
||||
$query = '';
|
||||
if ($foreignKey->hasOption('match')) {
|
||||
$query .= ' MATCH ' . $foreignKey->getOption('match');
|
||||
}
|
||||
$query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
|
||||
if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
|
||||
$query .= ' DEFERRABLE';
|
||||
} else {
|
||||
$query .= ' NOT DEFERRABLE';
|
||||
}
|
||||
if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) {
|
||||
$query .= ' INITIALLY DEFERRED';
|
||||
} else {
|
||||
$query .= ' INITIALLY IMMEDIATE';
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates the sql for altering an existing table on postgresql
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type *
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @see Doctrine_Export::alterTable()
|
||||
* @return array
|
||||
* @override
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
foreach ($diff->addedColumns as $column) {
|
||||
$query = 'ADD ' . $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
|
||||
}
|
||||
|
||||
foreach ($diff->removedColumns as $column) {
|
||||
$query = 'DROP ' . $column->getName();
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
|
||||
}
|
||||
|
||||
foreach ($diff->changedColumns AS $columnDiff) {
|
||||
$oldColumnName = $columnDiff->oldColumnName;
|
||||
$column = $columnDiff->column;
|
||||
|
||||
if ($columnDiff->hasChanged('type')) {
|
||||
$type = $column->getType();
|
||||
|
||||
// here was a server version check before, but DBAL API does not support this anymore.
|
||||
$query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this);
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
|
||||
}
|
||||
if ($columnDiff->hasChanged('default')) {
|
||||
$query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray());
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
|
||||
}
|
||||
if ($columnDiff->hasChanged('notnull')) {
|
||||
$query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL';
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns as $oldColumnName => $column) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getName();
|
||||
}
|
||||
|
||||
if ($diff->newName !== false) {
|
||||
$sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
|
||||
}
|
||||
|
||||
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL to create a sequence on this platform.
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Sequence $sequence
|
||||
* @return string
|
||||
*/
|
||||
public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
|
||||
{
|
||||
return 'CREATE SEQUENCE ' . $sequence->getName() .
|
||||
' INCREMENT BY ' . $sequence->getAllocationSize() .
|
||||
' MINVALUE ' . $sequence->getInitialValue() .
|
||||
' START ' . $sequence->getInitialValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop existing sequence
|
||||
* @param \Doctrine\DBAL\Schema\Sequence $sequence
|
||||
* @return string
|
||||
*/
|
||||
public function getDropSequenceSQL($sequence)
|
||||
{
|
||||
if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
|
||||
$sequence = $sequence->getName();
|
||||
}
|
||||
return 'DROP SEQUENCE ' . $sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ForeignKeyConstraint|string $foreignKey
|
||||
* @param Table|string $table
|
||||
* @return string
|
||||
*/
|
||||
public function getDropForeignKeySQL($foreignKey, $table)
|
||||
{
|
||||
return $this->getDropConstraintSQL($foreignKey, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL used to create a table.
|
||||
*
|
||||
* @param unknown_type $tableName
|
||||
* @param array $columns
|
||||
* @param array $options
|
||||
* @return unknown
|
||||
*/
|
||||
protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
|
||||
{
|
||||
$queryFields = $this->getColumnDeclarationListSQL($columns);
|
||||
|
||||
if (isset($options['primary']) && ! empty($options['primary'])) {
|
||||
$keyColumns = array_unique(array_values($options['primary']));
|
||||
$queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
|
||||
}
|
||||
|
||||
$query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')';
|
||||
|
||||
$sql[] = $query;
|
||||
|
||||
if (isset($options['indexes']) && ! empty($options['indexes'])) {
|
||||
foreach ($options['indexes'] AS $index) {
|
||||
$sql[] = $this->getCreateIndexSQL($index, $tableName);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['foreignKeys'])) {
|
||||
foreach ((array) $options['foreignKeys'] as $definition) {
|
||||
$sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postgres wants boolean values converted to the strings 'true'/'false'.
|
||||
*
|
||||
* @param array $item
|
||||
* @override
|
||||
*/
|
||||
public function convertBooleans($item)
|
||||
{
|
||||
if (is_array($item)) {
|
||||
foreach ($item as $key => $value) {
|
||||
if (is_bool($value) || is_numeric($item)) {
|
||||
$item[$key] = ($value) ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_bool($item) || is_numeric($item)) {
|
||||
$item = ($item) ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
public function getSequenceNextValSQL($sequenceName)
|
||||
{
|
||||
return "SELECT NEXTVAL('" . $sequenceName . "')";
|
||||
}
|
||||
|
||||
public function getSetTransactionIsolationSQL($level)
|
||||
{
|
||||
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
|
||||
. $this->_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'BOOLEAN';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! empty($field['autoincrement'])) {
|
||||
return 'SERIAL';
|
||||
}
|
||||
|
||||
return 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! empty($field['autoincrement'])) {
|
||||
return 'BIGSERIAL';
|
||||
}
|
||||
return 'BIGINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIMESTAMP(0) WITH TIME ZONE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIME';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
|
||||
*
|
||||
* @params array $field
|
||||
* @override
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'postgresql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the character casing of a column in an SQL result set.
|
||||
*
|
||||
* PostgreSQL returns all column names in SQL result sets in lowercase.
|
||||
*
|
||||
* @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 strtolower($column);
|
||||
}
|
||||
|
||||
public function getDateTimeFormatString()
|
||||
{
|
||||
return 'Y-m-d H:i:sO';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the insert sql for an empty insert statement
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $identifierColumnName
|
||||
* @return string $sql
|
||||
*/
|
||||
public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
|
||||
{
|
||||
return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTruncateTableSQL($tableName, $cascade = false)
|
||||
{
|
||||
return 'TRUNCATE '.$tableName.' '.($cascade)?'CASCADE':'';
|
||||
}
|
||||
|
||||
public function getReadLockSQL()
|
||||
{
|
||||
return 'FOR SHARE';
|
||||
}
|
||||
}
|
@ -1,436 +0,0 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* The SqlitePlatform class describes the specifics and dialects of the SQLite
|
||||
* database platform.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @todo Rename: SQLitePlatform
|
||||
*/
|
||||
class SqlitePlatform extends AbstractPlatform
|
||||
{
|
||||
/**
|
||||
* returns the regular expression operator
|
||||
*
|
||||
* @return string
|
||||
* @override
|
||||
*/
|
||||
public function getRegexpExpression()
|
||||
{
|
||||
return 'RLIKE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time.
|
||||
*
|
||||
* @return string sqlite function as string
|
||||
* @override
|
||||
*/
|
||||
public function getNowExpression($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
return 'time(\'now\')';
|
||||
case 'date':
|
||||
return 'date(\'now\')';
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'datetime(\'now\')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim a string, leading/trailing/both and with a given char which defaults to space.
|
||||
*
|
||||
* @param string $str
|
||||
* @param int $pos
|
||||
* @param string $char
|
||||
* @return string
|
||||
*/
|
||||
public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
|
||||
{
|
||||
$trimFn = '';
|
||||
$trimChar = ($char != false) ? (', ' . $char) : '';
|
||||
|
||||
if ($pos == self::TRIM_LEADING) {
|
||||
$trimFn = 'LTRIM';
|
||||
} else if($pos == self::TRIM_TRAILING) {
|
||||
$trimFn = 'RTRIM';
|
||||
} else {
|
||||
$trimFn = 'TRIM';
|
||||
}
|
||||
|
||||
return $trimFn . '(' . $str . $trimChar . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @override
|
||||
*/
|
||||
public function getSubstringExpression($value, $position, $length = null)
|
||||
{
|
||||
if ($length !== null) {
|
||||
return 'SUBSTR(' . $value . ', ' . $position . ', ' . $length . ')';
|
||||
}
|
||||
return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'LOCATE('.$str.', '.$substr.')';
|
||||
} else {
|
||||
return 'LOCATE('.$str.', '.$substr.', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
protected function _getTransactionIsolationLevelSQL($level)
|
||||
{
|
||||
switch ($level) {
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED:
|
||||
return 0;
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED:
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ:
|
||||
case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE:
|
||||
return 1;
|
||||
default:
|
||||
return parent::_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
}
|
||||
|
||||
public function getSetTransactionIsolationSQL($level)
|
||||
{
|
||||
return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function prefersIdentityColumns()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'BOOLEAN';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTinyIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getMediumIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return $this->_getCommonIntegerTypeDeclarationSQL($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATETIME';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIME';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
{
|
||||
$autoinc = ! empty($columnDef['autoincrement']) ? ' AUTOINCREMENT' : '';
|
||||
$pk = ! empty($columnDef['primary']) && ! empty($autoinc) ? ' PRIMARY KEY' : '';
|
||||
|
||||
return 'INTEGER' . $pk . $autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
* array(
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @param array $options An associative array of table options:
|
||||
*
|
||||
* @return void
|
||||
* @override
|
||||
*/
|
||||
protected function _getCreateTableSQL($name, array $columns, array $options = array())
|
||||
{
|
||||
$queryFields = $this->getColumnDeclarationListSQL($columns);
|
||||
|
||||
$autoinc = false;
|
||||
foreach($columns as $field) {
|
||||
if (isset($field['autoincrement']) && $field['autoincrement']) {
|
||||
$autoinc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $autoinc && isset($options['primary']) && ! empty($options['primary'])) {
|
||||
$keyColumns = array_unique(array_values($options['primary']));
|
||||
$keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns);
|
||||
$queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')';
|
||||
}
|
||||
|
||||
$query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')';
|
||||
|
||||
if (isset($options['indexes']) && ! empty($options['indexes'])) {
|
||||
foreach ($options['indexes'] as $index => $indexDef) {
|
||||
$query[] = $this->getCreateIndexSQL($indexDef, $name);
|
||||
}
|
||||
}
|
||||
if (isset($options['unique']) && ! empty($options['unique'])) {
|
||||
foreach ($options['unique'] as $index => $indexDef) {
|
||||
$query[] = $this->getCreateIndexSQL($indexDef, $name);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
|
||||
}
|
||||
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
{
|
||||
return 'CLOB';
|
||||
}
|
||||
|
||||
public function getListTableConstraintsSQL($table)
|
||||
{
|
||||
return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = '$table' AND sql NOT NULL ORDER BY name";
|
||||
}
|
||||
|
||||
public function getListTableColumnsSQL($table)
|
||||
{
|
||||
return "PRAGMA table_info($table)";
|
||||
}
|
||||
|
||||
public function getListTableIndexesSQL($table)
|
||||
{
|
||||
return "PRAGMA index_list($table)";
|
||||
}
|
||||
|
||||
public function getListTablesSQL()
|
||||
{
|
||||
return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' "
|
||||
. "UNION ALL SELECT name FROM sqlite_temp_master "
|
||||
. "WHERE type = 'table' ORDER BY name";
|
||||
}
|
||||
|
||||
public function getListViewsSQL($database)
|
||||
{
|
||||
return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL";
|
||||
}
|
||||
|
||||
public function getCreateViewSQL($name, $sql)
|
||||
{
|
||||
return 'CREATE VIEW ' . $name . ' AS ' . $sql;
|
||||
}
|
||||
|
||||
public function getDropViewSQL($name)
|
||||
{
|
||||
return 'DROP VIEW '. $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQLite does support foreign key constraints, but only in CREATE TABLE statements...
|
||||
* This really limits their usefulness and requires SQLite specific handling, so
|
||||
* we simply say that SQLite does NOT support foreign keys for now...
|
||||
*
|
||||
* @return boolean FALSE
|
||||
* @override
|
||||
*/
|
||||
public function supportsForeignKeyConstraints()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function supportsAlterTable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sqlite';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTruncateTableSQL($tableName, $cascade = false)
|
||||
{
|
||||
return 'DELETE FROM '.$tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* User-defined function for Sqlite that is used with PDO::sqliteCreateFunction()
|
||||
*
|
||||
* @param int|float $value
|
||||
* @return float
|
||||
*/
|
||||
static public function udfSqrt($value)
|
||||
{
|
||||
return sqrt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* User-defined function for Sqlite that implements MOD(a, b)
|
||||
*/
|
||||
static public function udfMod($a, $b)
|
||||
{
|
||||
return ($a % $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @param string $substr
|
||||
* @param int $offset
|
||||
*/
|
||||
static public function udfLocate($str, $substr, $offset = 0)
|
||||
{
|
||||
$pos = strpos($str, $substr, $offset);
|
||||
if ($pos !== false) {
|
||||
return $pos+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getForUpdateSql()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* The abstract asset allows to reset the name of all assets without publishing this to the public userland.
|
||||
*
|
||||
* This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
|
||||
* array($tableName => Table($tableName)); if you want to rename the table, you have to make sure
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
abstract class AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_name;
|
||||
|
||||
/**
|
||||
* Set name of this asset
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function _setName($name)
|
||||
{
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return name of this schema asset.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an identifier from a list of column names obeying a certain string length.
|
||||
*
|
||||
* This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
|
||||
* however building idents automatically for foreign keys, composite keys or such can easily create
|
||||
* very long names.
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $postfix
|
||||
* @param int $maxSize
|
||||
* @return string
|
||||
*/
|
||||
protected function _generateIdentifierName($columnNames, $postfix='', $maxSize=30)
|
||||
{
|
||||
$columnCount = count($columnNames);
|
||||
$postfixLen = strlen($postfix);
|
||||
$parts = array_map(function($columnName) use($columnCount, $postfixLen, $maxSize) {
|
||||
return substr($columnName, -floor(($maxSize-$postfixLen)/$columnCount - 1));
|
||||
}, $columnNames);
|
||||
$parts[] = $postfix;
|
||||
|
||||
return trim(implode("_", $parts), '_');
|
||||
}
|
||||
}
|
@ -1,774 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Types;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* Base class for schema managers. Schema managers are used to inspect and/or
|
||||
* modify the database schema/structure.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class AbstractSchemaManager
|
||||
{
|
||||
/**
|
||||
* Holds instance of the Doctrine connection for this schema manager
|
||||
*
|
||||
* @var \Doctrine\DBAL\Connection
|
||||
*/
|
||||
protected $_conn;
|
||||
|
||||
/**
|
||||
* Holds instance of the database platform used for this schema manager
|
||||
*
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
protected $_platform;
|
||||
|
||||
/**
|
||||
* Constructor. Accepts the Connection instance to manage the schema for
|
||||
*
|
||||
* @param \Doctrine\DBAL\Connection $conn
|
||||
*/
|
||||
public function __construct(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
$this->_conn = $conn;
|
||||
$this->_platform = $this->_conn->getDatabasePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return associated platform.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Platform\AbstractPlatform
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return $this->_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try any method on the schema manager. Normally a method throws an
|
||||
* exception when your DBMS doesn't support it or if an error occurs.
|
||||
* This method allows you to try and method on your SchemaManager
|
||||
* instance and will return false if it does not work or is not supported.
|
||||
*
|
||||
* <code>
|
||||
* $result = $sm->tryMethod('dropView', 'view_name');
|
||||
* </code>
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function tryMethod()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$method = $args[0];
|
||||
unset($args[0]);
|
||||
$args = array_values($args);
|
||||
|
||||
try {
|
||||
return call_user_func_array(array($this, $method), $args);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available databases for this connection
|
||||
*
|
||||
* @return array $databases
|
||||
*/
|
||||
public function listDatabases()
|
||||
{
|
||||
$sql = $this->_platform->getListDatabasesSQL();
|
||||
|
||||
$databases = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableDatabasesList($databases);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available sequences for this connection
|
||||
*
|
||||
* @return Sequence[]
|
||||
*/
|
||||
public function listSequences($database = null)
|
||||
{
|
||||
if (is_null($database)) {
|
||||
$database = $this->_conn->getDatabase();
|
||||
}
|
||||
$sql = $this->_platform->getListSequencesSQL($database);
|
||||
|
||||
$sequences = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableSequencesList($sequences);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the columns for a given table.
|
||||
*
|
||||
* In contrast to other libraries and to the old version of Doctrine,
|
||||
* this column definition does try to contain the 'primary' field for
|
||||
* the reason that it is not portable accross different RDBMS. Use
|
||||
* {@see listTableIndexes($tableName)} to retrieve the primary key
|
||||
* of a table. We're a RDBMS specifies more details these are held
|
||||
* in the platformDetails array.
|
||||
*
|
||||
* @param string $table The name of the table.
|
||||
* @return Column[]
|
||||
*/
|
||||
public function listTableColumns($table)
|
||||
{
|
||||
$sql = $this->_platform->getListTableColumnsSQL($table);
|
||||
|
||||
$tableColumns = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableTableColumnList($tableColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the indexes for a given table returning an array of Index instances.
|
||||
*
|
||||
* Keys of the portable indexes list are all lower-cased.
|
||||
*
|
||||
* @param string $table The name of the table
|
||||
* @return Index[] $tableIndexes
|
||||
*/
|
||||
public function listTableIndexes($table)
|
||||
{
|
||||
$sql = $this->_platform->getListTableIndexesSQL($table);
|
||||
|
||||
$tableIndexes = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableTableIndexesList($tableIndexes, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all tables in the current database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listTableNames()
|
||||
{
|
||||
$sql = $this->_platform->getListTablesSQL();
|
||||
|
||||
$tables = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableTablesList($tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the tables for this connection
|
||||
*
|
||||
* @return Table[]
|
||||
*/
|
||||
public function listTables()
|
||||
{
|
||||
$tableNames = $this->listTableNames();
|
||||
|
||||
$tables = array();
|
||||
foreach ($tableNames AS $tableName) {
|
||||
$tables[] = $this->listTableDetails($tableName);
|
||||
}
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return Table
|
||||
*/
|
||||
public function listTableDetails($tableName)
|
||||
{
|
||||
$columns = $this->listTableColumns($tableName);
|
||||
$foreignKeys = array();
|
||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
||||
$foreignKeys = $this->listTableForeignKeys($tableName);
|
||||
}
|
||||
$indexes = $this->listTableIndexes($tableName);
|
||||
|
||||
$idGeneratorType = Table::ID_NONE;
|
||||
foreach ($columns AS $column) {
|
||||
if ($column->hasPlatformOption('autoincrement') && $column->getPlatformOption('autoincrement')) {
|
||||
$idGeneratorType = Table::ID_IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
return new Table($tableName, $columns, $indexes, $foreignKeys, $idGeneratorType, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* List the views this connection has
|
||||
*
|
||||
* @return View[]
|
||||
*/
|
||||
public function listViews()
|
||||
{
|
||||
$database = $this->_conn->getDatabase();
|
||||
$sql = $this->_platform->getListViewsSQL($database);
|
||||
$views = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableViewsList($views);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the foreign keys for the given table
|
||||
*
|
||||
* @param string $table The name of the table
|
||||
* @return ForeignKeyConstraint[]
|
||||
*/
|
||||
public function listTableForeignKeys($table, $database = null)
|
||||
{
|
||||
if (is_null($database)) {
|
||||
$database = $this->_conn->getDatabase();
|
||||
}
|
||||
$sql = $this->_platform->getListTableForeignKeysSQL($table, $database);
|
||||
$tableForeignKeys = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableTableForeignKeysList($tableForeignKeys);
|
||||
}
|
||||
|
||||
/* drop*() Methods */
|
||||
|
||||
/**
|
||||
* Drops a database.
|
||||
*
|
||||
* NOTE: You can not drop the database this SchemaManager is currently connected to.
|
||||
*
|
||||
* @param string $database The name of the database to drop
|
||||
*/
|
||||
public function dropDatabase($database)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropDatabaseSQL($database));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the given table
|
||||
*
|
||||
* @param string $table The name of the table to drop
|
||||
*/
|
||||
public function dropTable($table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropTableSQL($table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the index from the given table
|
||||
*
|
||||
* @param Index|string $index The name of the index
|
||||
* @param string|Table $table The name of the table
|
||||
*/
|
||||
public function dropIndex($index, $table)
|
||||
{
|
||||
if($index instanceof Index) {
|
||||
$index = $index->getName();
|
||||
}
|
||||
|
||||
$this->_execSql($this->_platform->getDropIndexSQL($index, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the constraint from the given table
|
||||
*
|
||||
* @param Constraint $constraint
|
||||
* @param string $table The name of the table
|
||||
*/
|
||||
public function dropConstraint(Constraint $constraint, $table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropConstraintSQL($constraint, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a foreign key from a table.
|
||||
*
|
||||
* @param ForeignKeyConstraint|string $table The name of the table with the foreign key.
|
||||
* @param Table|string $name The name of the foreign key.
|
||||
* @return boolean $result
|
||||
*/
|
||||
public function dropForeignKey($foreignKey, $table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropForeignKeySQL($foreignKey, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a sequence with a given name.
|
||||
*
|
||||
* @param string $name The name of the sequence to drop.
|
||||
*/
|
||||
public function dropSequence($name)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropSequenceSQL($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a view
|
||||
*
|
||||
* @param string $name The name of the view
|
||||
* @return boolean $result
|
||||
*/
|
||||
public function dropView($name)
|
||||
{
|
||||
$this->_execSql($this->_platform->getDropViewSQL($name));
|
||||
}
|
||||
|
||||
/* create*() Methods */
|
||||
|
||||
/**
|
||||
* Creates a new database.
|
||||
*
|
||||
* @param string $database The name of the database to create.
|
||||
*/
|
||||
public function createDatabase($database)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateDatabaseSQL($database));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new table.
|
||||
*
|
||||
* @param Table $table
|
||||
* @param int $createFlags
|
||||
*/
|
||||
public function createTable(Table $table)
|
||||
{
|
||||
$createFlags = AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS;
|
||||
$this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sequence
|
||||
*
|
||||
* @param Sequence $sequence
|
||||
* @throws Doctrine\DBAL\ConnectionException if something fails at database level
|
||||
*/
|
||||
public function createSequence($sequence)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateSequenceSQL($sequence));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a constraint on a table
|
||||
*
|
||||
* @param Constraint $constraint
|
||||
* @param string|Table $table
|
||||
*/
|
||||
public function createConstraint(Constraint $constraint, $table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateConstraintSQL($constraint, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new index on a table
|
||||
*
|
||||
* @param Index $index
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
*/
|
||||
public function createIndex(Index $index, $table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateIndexSQL($index, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function createForeignKey(ForeignKeyConstraint $foreignKey, $table)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateForeignKeySQL($foreignKey, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new view
|
||||
*
|
||||
* @param View $view
|
||||
*/
|
||||
public function createView(View $view)
|
||||
{
|
||||
$this->_execSql($this->_platform->getCreateViewSQL($view->getName(), $view->getSql()));
|
||||
}
|
||||
|
||||
/* dropAndCreate*() Methods */
|
||||
|
||||
/**
|
||||
* Drop and create a constraint
|
||||
*
|
||||
* @param Constraint $constraint
|
||||
* @param string $table
|
||||
* @see dropConstraint()
|
||||
* @see createConstraint()
|
||||
*/
|
||||
public function dropAndCreateConstraint(Constraint $constraint, $table)
|
||||
{
|
||||
$this->tryMethod('dropConstraint', $constraint, $table);
|
||||
$this->createConstraint($constraint, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and create a new index on a table
|
||||
*
|
||||
* @param string|Table $table name of the table on which the index is to be created
|
||||
* @param Index $index
|
||||
*/
|
||||
public function dropAndCreateIndex(Index $index, $table)
|
||||
{
|
||||
$this->tryMethod('dropIndex', $index->getName(), $table);
|
||||
$this->createIndex($index, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and create a new foreign key
|
||||
*
|
||||
* @param ForeignKeyConstraint $foreignKey associative array that defines properties of the foreign key to be created.
|
||||
* @param string|Table $table name of the table on which the foreign key is to be created
|
||||
*/
|
||||
public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
|
||||
{
|
||||
$this->tryMethod('dropForeignKey', $foreignKey, $table);
|
||||
$this->createForeignKey($foreignKey, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and create a new sequence
|
||||
*
|
||||
* @param Sequence $sequence
|
||||
* @throws Doctrine\DBAL\ConnectionException if something fails at database level
|
||||
*/
|
||||
public function dropAndCreateSequence(Sequence $sequence)
|
||||
{
|
||||
$this->tryMethod('createSequence', $seqName, $start, $allocationSize);
|
||||
$this->createSequence($seqName, $start, $allocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and create a new table.
|
||||
*
|
||||
* @param Table $table
|
||||
*/
|
||||
public function dropAndCreateTable(Table $table)
|
||||
{
|
||||
$this->tryMethod('dropTable', $table->getName());
|
||||
$this->createTable($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and creates a new database.
|
||||
*
|
||||
* @param string $database The name of the database to create.
|
||||
*/
|
||||
public function dropAndCreateDatabase($database)
|
||||
{
|
||||
$this->tryMethod('dropDatabase', $database);
|
||||
$this->createDatabase($database);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop and create a new view
|
||||
*
|
||||
* @param View $view
|
||||
*/
|
||||
public function dropAndCreateView(View $view)
|
||||
{
|
||||
$this->tryMethod('dropView', $view->getName());
|
||||
$this->createView($view);
|
||||
}
|
||||
|
||||
/* alterTable() Methods */
|
||||
|
||||
/**
|
||||
* Alter an existing tables schema
|
||||
*
|
||||
* @param TableDiff $tableDiff
|
||||
*/
|
||||
public function alterTable(TableDiff $tableDiff)
|
||||
{
|
||||
$queries = $this->_platform->getAlterTableSQL($tableDiff);
|
||||
if (is_array($queries) && count($queries)) {
|
||||
foreach ($queries AS $ddlQuery) {
|
||||
$this->_execSql($ddlQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a given table to another name
|
||||
*
|
||||
* @param string $name The current name of the table
|
||||
* @param string $newName The new name of the table
|
||||
*/
|
||||
public function renameTable($name, $newName)
|
||||
{
|
||||
$tableDiff = new TableDiff($name);
|
||||
$tableDiff->newName = $newName;
|
||||
$this->alterTable($tableDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods for filtering return values of list*() methods to convert
|
||||
* the native DBMS data definition to a portable Doctrine definition
|
||||
*/
|
||||
|
||||
protected function _getPortableDatabasesList($databases)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($databases as $key => $value) {
|
||||
if ($value = $this->_getPortableDatabaseDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableDatabaseDefinition($database)
|
||||
{
|
||||
return $database;
|
||||
}
|
||||
|
||||
protected function _getPortableFunctionsList($functions)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($functions as $key => $value) {
|
||||
if ($value = $this->_getPortableFunctionDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableFunctionDefinition($function)
|
||||
{
|
||||
return $function;
|
||||
}
|
||||
|
||||
protected function _getPortableTriggersList($triggers)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($triggers as $key => $value) {
|
||||
if ($value = $this->_getPortableTriggerDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableTriggerDefinition($trigger)
|
||||
{
|
||||
return $trigger;
|
||||
}
|
||||
|
||||
protected function _getPortableSequencesList($sequences)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($sequences as $key => $value) {
|
||||
if ($value = $this->_getPortableSequenceDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $sequence
|
||||
* @return Sequence
|
||||
*/
|
||||
protected function _getPortableSequenceDefinition($sequence)
|
||||
{
|
||||
throw DBALException::notSupported('Sequences');
|
||||
}
|
||||
|
||||
/**
|
||||
* Independent of the database the keys of the column list result are lowercased.
|
||||
*
|
||||
* The name of the created column instance however is kept in its case.
|
||||
*
|
||||
* @param array $tableColumns
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableColumnList($tableColumns)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($tableColumns as $key => $column) {
|
||||
if ($column = $this->_getPortableTableColumnDefinition($column)) {
|
||||
$name = strtolower($column->getName());
|
||||
$list[$name] = $column;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Table Column Definition
|
||||
*
|
||||
* @param array $tableColumn
|
||||
* @return Column
|
||||
*/
|
||||
abstract protected function _getPortableTableColumnDefinition($tableColumn);
|
||||
|
||||
/**
|
||||
* Aggregate and group the index results according to the required data result.
|
||||
*
|
||||
* @param array $tableIndexRows
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
|
||||
{
|
||||
$result = array();
|
||||
foreach($tableIndexRows AS $tableIndex) {
|
||||
$indexName = $keyName = $tableIndex['key_name'];
|
||||
if($tableIndex['primary']) {
|
||||
$keyName = 'primary';
|
||||
}
|
||||
$keyName = strtolower($keyName);
|
||||
|
||||
if(!isset($result[$keyName])) {
|
||||
$result[$keyName] = array(
|
||||
'name' => $indexName,
|
||||
'columns' => array($tableIndex['column_name']),
|
||||
'unique' => $tableIndex['non_unique'] ? false : true,
|
||||
'primary' => $tableIndex['primary'],
|
||||
);
|
||||
} else {
|
||||
$result[$keyName]['columns'][] = $tableIndex['column_name'];
|
||||
}
|
||||
}
|
||||
|
||||
$indexes = array();
|
||||
foreach($result AS $indexKey => $data) {
|
||||
$indexes[$indexKey] = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
protected function _getPortableTablesList($tables)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($tables as $key => $value) {
|
||||
if ($value = $this->_getPortableTableDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableTableDefinition($table)
|
||||
{
|
||||
return $table;
|
||||
}
|
||||
|
||||
protected function _getPortableUsersList($users)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($users as $key => $value) {
|
||||
if ($value = $this->_getPortableUserDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableUserDefinition($user)
|
||||
{
|
||||
return $user;
|
||||
}
|
||||
|
||||
protected function _getPortableViewsList($views)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($views as $key => $value) {
|
||||
if ($view = $this->_getPortableViewDefinition($value)) {
|
||||
$viewName = strtolower($view->getName());
|
||||
$list[$viewName] = $view;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function _getPortableTableForeignKeysList($tableForeignKeys)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($tableForeignKeys as $key => $value) {
|
||||
if ($value = $this->_getPortableTableForeignKeyDefinition($value)) {
|
||||
$list[] = $value;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
||||
{
|
||||
return $tableForeignKey;
|
||||
}
|
||||
|
||||
protected function _execSql($sql)
|
||||
{
|
||||
foreach ((array) $sql as $query) {
|
||||
$this->_conn->executeUpdate($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a schema instance for the current database.
|
||||
*
|
||||
* @return Schema
|
||||
*/
|
||||
public function createSchema()
|
||||
{
|
||||
$sequences = array();
|
||||
if($this->_platform->supportsSequences()) {
|
||||
$sequences = $this->listSequences();
|
||||
}
|
||||
$tables = $this->listTables();
|
||||
|
||||
return new Schema($tables, $sequences, $this->createSchemaConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the configuration for this schema.
|
||||
*
|
||||
* @return SchemaConfig
|
||||
*/
|
||||
public function createSchemaConfig()
|
||||
{
|
||||
$schemaConfig = new SchemaConfig();
|
||||
$schemaConfig->setExplicitForeignKeyIndexes($this->_platform->createsExplicitIndexForForeignKeys());
|
||||
$schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength());
|
||||
|
||||
return $schemaConfig;
|
||||
}
|
||||
}
|
@ -1,331 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use \Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
|
||||
/**
|
||||
* Object representation of a database column
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Column extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Types\Type
|
||||
*/
|
||||
protected $_type;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_length = 255;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_precision = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_scale = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_unsigned = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_fixed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_notnull = true;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_default = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_platformOptions = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_columnDefinition = null;
|
||||
|
||||
/**
|
||||
* Create a new Column
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param Doctrine\DBAL\Types\Type $type
|
||||
* @param int $length
|
||||
* @param bool $notNull
|
||||
* @param mixed $default
|
||||
* @param bool $unsigned
|
||||
* @param bool $fixed
|
||||
* @param int $precision
|
||||
* @param int $scale
|
||||
* @param array $platformOptions
|
||||
*/
|
||||
public function __construct($columnName, Type $type, array $options=array())
|
||||
{
|
||||
$this->_setName($columnName);
|
||||
$this->setType($type);
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return Column
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
foreach ($options AS $name => $value) {
|
||||
$method = "set".$name;
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $type
|
||||
* @return Column
|
||||
*/
|
||||
public function setType(Type $type)
|
||||
{
|
||||
$this->_type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return Column
|
||||
*/
|
||||
public function setLength($length)
|
||||
{
|
||||
if($length !== null) {
|
||||
$this->_length = (int)$length;
|
||||
} else {
|
||||
$this->_length = null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $precision
|
||||
* @return Column
|
||||
*/
|
||||
public function setPrecision($precision)
|
||||
{
|
||||
$this->_precision = (int)$precision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $scale
|
||||
* @return Column
|
||||
*/
|
||||
public function setScale($scale)
|
||||
{
|
||||
$this->_scale = $scale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $unsigned
|
||||
* @return Column
|
||||
*/
|
||||
public function setUnsigned($unsigned)
|
||||
{
|
||||
$this->_unsigned = (bool)$unsigned;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $fixed
|
||||
* @return Column
|
||||
*/
|
||||
public function setFixed($fixed)
|
||||
{
|
||||
$this->_fixed = (bool)$fixed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $notnull
|
||||
* @return Column
|
||||
*/
|
||||
public function setNotnull($notnull)
|
||||
{
|
||||
$this->_notnull = (bool)$notnull;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $default
|
||||
* @return Column
|
||||
*/
|
||||
public function setDefault($default)
|
||||
{
|
||||
$this->_default = $default;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $platformOptions
|
||||
* @return Column
|
||||
*/
|
||||
public function setPlatformOptions(array $platformOptions)
|
||||
{
|
||||
$this->_platformOptions = $platformOptions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return Column
|
||||
*/
|
||||
public function setPlatformOption($name, $value)
|
||||
{
|
||||
$this->_platformOptions[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string
|
||||
* @return Column
|
||||
*/
|
||||
public function setColumnDefinition($value)
|
||||
{
|
||||
$this->_columnDefinition = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
public function getLength()
|
||||
{
|
||||
return $this->_length;
|
||||
}
|
||||
|
||||
public function getPrecision()
|
||||
{
|
||||
return $this->_precision;
|
||||
}
|
||||
|
||||
public function getScale()
|
||||
{
|
||||
return $this->_scale;
|
||||
}
|
||||
|
||||
public function getUnsigned()
|
||||
{
|
||||
return $this->_unsigned;
|
||||
}
|
||||
|
||||
public function getFixed()
|
||||
{
|
||||
return $this->_fixed;
|
||||
}
|
||||
|
||||
public function getNotnull()
|
||||
{
|
||||
return $this->_notnull;
|
||||
}
|
||||
|
||||
public function getDefault()
|
||||
{
|
||||
return $this->_default;
|
||||
}
|
||||
|
||||
public function getPlatformOptions()
|
||||
{
|
||||
return $this->_platformOptions;
|
||||
}
|
||||
|
||||
public function hasPlatformOption($name)
|
||||
{
|
||||
return isset($this->_platformOptions[$name]);
|
||||
}
|
||||
|
||||
public function getPlatformOption($name)
|
||||
{
|
||||
return $this->_platformOptions[$name];
|
||||
}
|
||||
|
||||
public function getColumnDefinition()
|
||||
{
|
||||
return $this->_columnDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(\Doctrine\DBAL\Schema\Visitor $visitor)
|
||||
{
|
||||
$visitor->accept($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_merge(array(
|
||||
'name' => $this->_name,
|
||||
'type' => $this->_type,
|
||||
'default' => $this->_default,
|
||||
'notnull' => $this->_notnull,
|
||||
'length' => $this->_length,
|
||||
'precision' => $this->_precision,
|
||||
'scale' => $this->_scale,
|
||||
'fixed' => $this->_fixed,
|
||||
'unsigned' => $this->_unsigned,
|
||||
'columnDefinition' => $this->_columnDefinition,
|
||||
), $this->_platformOptions);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Represent the change of a column
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class ColumnDiff
|
||||
{
|
||||
public $oldColumnName;
|
||||
|
||||
/**
|
||||
* @var Column
|
||||
*/
|
||||
public $column;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $changedProperties = array();
|
||||
|
||||
public function __construct($oldColumnName, Column $column, array $changedProperties = array())
|
||||
{
|
||||
$this->oldColumnName = $oldColumnName;
|
||||
$this->column = $column;
|
||||
$this->changedProperties = $changedProperties;
|
||||
}
|
||||
|
||||
public function hasChanged($propertyName)
|
||||
{
|
||||
return in_array($propertyName, $this->changedProperties);
|
||||
}
|
||||
}
|
@ -1,395 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Compare to Schemas and return an instance of SchemaDiff
|
||||
*
|
||||
* @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Comparator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_checkColumnPlatformOptions = array();
|
||||
|
||||
/**
|
||||
* @param string $optionName
|
||||
*/
|
||||
public function addColumnPlatformOptionCheck($optionName)
|
||||
{
|
||||
$this->_checkColumnPlatformOptions[] = $optionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $fromSchema
|
||||
* @param Schema $toSchema
|
||||
* @return SchemaDiff
|
||||
*/
|
||||
static public function compareSchemas( Schema $fromSchema, Schema $toSchema )
|
||||
{
|
||||
$c = new self();
|
||||
return $c->compare($fromSchema, $toSchema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema.
|
||||
*
|
||||
* The returned diferences are returned in such a way that they contain the
|
||||
* operations to change the schema stored in $fromSchema to the schema that is
|
||||
* stored in $toSchema.
|
||||
*
|
||||
* @param Schema $fromSchema
|
||||
* @param Schema $toSchema
|
||||
*
|
||||
* @return SchemaDiff
|
||||
*/
|
||||
public function compare(Schema $fromSchema, Schema $toSchema)
|
||||
{
|
||||
if ($fromSchema->hasExplicitForeignKeyIndexes() && !$toSchema->hasExplicitForeignKeyIndexes()) {
|
||||
$toSchema->visit(new \Doctrine\DBAL\Schema\Visitor\FixSchema(true));
|
||||
}
|
||||
|
||||
$diff = new SchemaDiff();
|
||||
|
||||
$foreignKeysToTable = array();
|
||||
|
||||
foreach ( $toSchema->getTables() AS $tableName => $table ) {
|
||||
if ( !$fromSchema->hasTable($tableName) ) {
|
||||
$diff->newTables[$tableName] = $table;
|
||||
} else {
|
||||
$tableDifferences = $this->diffTable( $fromSchema->getTable($tableName), $table );
|
||||
if ( $tableDifferences !== false ) {
|
||||
$diff->changedTables[$tableName] = $tableDifferences;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there are tables removed */
|
||||
foreach ( $fromSchema->getTables() AS $tableName => $table ) {
|
||||
if ( !$toSchema->hasTable($tableName) ) {
|
||||
$diff->removedTables[$tableName] = $table;
|
||||
}
|
||||
|
||||
// also remember all foreign keys that point to a specific table
|
||||
foreach ($table->getForeignKeys() AS $foreignKey) {
|
||||
$foreignTable = strtolower($foreignKey->getForeignTableName());
|
||||
if (!isset($foreignKeysToTable[$foreignTable])) {
|
||||
$foreignKeysToTable[$foreignTable] = array();
|
||||
}
|
||||
$foreignKeysToTable[$foreignTable][] = $foreignKey;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($diff->removedTables AS $tableName => $table) {
|
||||
if (isset($foreignKeysToTable[$tableName])) {
|
||||
$diff->orphanedForeignKeys = array_merge($diff->orphanedForeignKeys, $foreignKeysToTable[$tableName]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $toSchema->getSequences() AS $sequenceName => $sequence) {
|
||||
if (!$fromSchema->hasSequence($sequenceName)) {
|
||||
$diff->newSequences[] = $sequence;
|
||||
} else {
|
||||
if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) {
|
||||
$diff->changedSequences[] = $fromSchema->getSequence($sequenceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($fromSchema->getSequences() AS $sequenceName => $sequence) {
|
||||
if (!$toSchema->hasSequence($sequenceName)) {
|
||||
$diff->removedSequences[] = $sequence;
|
||||
}
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Sequence $sequence1
|
||||
* @param Sequence $sequence2
|
||||
*/
|
||||
public function diffSequence(Sequence $sequence1, Sequence $sequence2)
|
||||
{
|
||||
if($sequence1->getAllocationSize() != $sequence2->getAllocationSize()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if($sequence1->getInitialValue() != $sequence2->getInitialValue()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference between the tables $table1 and $table2.
|
||||
*
|
||||
* If there are no differences this method returns the boolean false.
|
||||
*
|
||||
* @param Table $table1
|
||||
* @param Table $table2
|
||||
*
|
||||
* @return bool|TableDiff
|
||||
*/
|
||||
public function diffTable(Table $table1, Table $table2)
|
||||
{
|
||||
$changes = 0;
|
||||
$tableDifferences = new TableDiff($table1->getName());
|
||||
|
||||
$table1Columns = $table1->getColumns();
|
||||
$table2Columns = $table2->getColumns();
|
||||
|
||||
/* See if all the fields in table 1 exist in table 2 */
|
||||
foreach ( $table2Columns as $columnName => $column ) {
|
||||
if ( !$table1->hasColumn($columnName) ) {
|
||||
$tableDifferences->addedColumns[$columnName] = $column;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
/* See if there are any removed fields in table 2 */
|
||||
foreach ( $table1Columns as $columnName => $column ) {
|
||||
if ( !$table2->hasColumn($columnName) ) {
|
||||
$tableDifferences->removedColumns[$columnName] = $column;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
foreach ( $table1Columns as $columnName => $column ) {
|
||||
if ( $table2->hasColumn($columnName) ) {
|
||||
$changedProperties = $this->diffColumn( $column, $table2->getColumn($columnName) );
|
||||
if (count($changedProperties) ) {
|
||||
$columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties);
|
||||
$tableDifferences->changedColumns[$column->getName()] = $columnDiff;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
|
||||
foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) {
|
||||
foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) {
|
||||
if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
|
||||
$tableDifferences->renamedColumns[$removedColumn->getName()] = $addedColumn;
|
||||
unset($tableDifferences->addedColumns[$addedColumnName]);
|
||||
unset($tableDifferences->removedColumns[$removedColumnName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table1Indexes = $table1->getIndexes();
|
||||
$table2Indexes = $table2->getIndexes();
|
||||
|
||||
foreach ($table2Indexes AS $index2Name => $index2Definition) {
|
||||
foreach ($table1Indexes AS $index1Name => $index1Definition) {
|
||||
if ($this->diffIndex($index1Definition, $index2Definition) === false) {
|
||||
unset($table1Indexes[$index1Name]);
|
||||
unset($table2Indexes[$index2Name]);
|
||||
} else {
|
||||
if ($index1Name == $index2Name) {
|
||||
$tableDifferences->changedIndexes[$index2Name] = $table2Indexes[$index2Name];
|
||||
unset($table1Indexes[$index1Name]);
|
||||
unset($table2Indexes[$index2Name]);
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($table1Indexes AS $index1Name => $index1Definition) {
|
||||
$tableDifferences->removedIndexes[$index1Name] = $index1Definition;
|
||||
$changes++;
|
||||
}
|
||||
|
||||
foreach ($table2Indexes AS $index2Name => $index2Definition) {
|
||||
$tableDifferences->addedIndexes[$index2Name] = $index2Definition;
|
||||
$changes++;
|
||||
}
|
||||
|
||||
$fromFkeys = $table1->getForeignKeys();
|
||||
$toFkeys = $table2->getForeignKeys();
|
||||
|
||||
foreach ($fromFkeys AS $key1 => $constraint1) {
|
||||
foreach ($toFkeys AS $key2 => $constraint2) {
|
||||
if($this->diffForeignKey($constraint1, $constraint2) === false) {
|
||||
unset($fromFkeys[$key1]);
|
||||
unset($toFkeys[$key2]);
|
||||
} else {
|
||||
if (strtolower($constraint1->getName()) == strtolower($constraint2->getName())) {
|
||||
$tableDifferences->changedForeignKeys[] = $constraint2;
|
||||
$changes++;
|
||||
unset($fromFkeys[$key1]);
|
||||
unset($toFkeys[$key2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($fromFkeys AS $key1 => $constraint1) {
|
||||
$tableDifferences->removedForeignKeys[] = $constraint1;
|
||||
$changes++;
|
||||
}
|
||||
|
||||
foreach ($toFkeys AS $key2 => $constraint2) {
|
||||
$tableDifferences->addedForeignKeys[] = $constraint2;
|
||||
$changes++;
|
||||
}
|
||||
|
||||
return $changes ? $tableDifferences : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ForeignKeyConstraint $key1
|
||||
* @param ForeignKeyConstraint $key2
|
||||
* @return bool
|
||||
*/
|
||||
public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2)
|
||||
{
|
||||
if (array_map('strtolower', $key1->getLocalColumns()) != array_map('strtolower', $key2->getLocalColumns())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array_map('strtolower', $key1->getForeignColumns()) != array_map('strtolower', $key2->getForeignColumns())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->onUpdate() != $key2->onUpdate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->onDelete() != $key2->onDelete()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference between the fields $field1 and $field2.
|
||||
*
|
||||
* If there are differences this method returns $field2, otherwise the
|
||||
* boolean false.
|
||||
*
|
||||
* @param Column $column1
|
||||
* @param Column $column2
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function diffColumn(Column $column1, Column $column2)
|
||||
{
|
||||
$changedProperties = array();
|
||||
if ( $column1->getType() != $column2->getType() ) {
|
||||
$changedProperties[] = 'type';
|
||||
}
|
||||
|
||||
if ($column1->getNotnull() != $column2->getNotnull()) {
|
||||
$changedProperties[] = 'notnull';
|
||||
}
|
||||
|
||||
if ($column1->getDefault() != $column2->getDefault()) {
|
||||
$changedProperties[] = 'default';
|
||||
}
|
||||
|
||||
if ($column1->getUnsigned() != $column2->getUnsigned()) {
|
||||
$changedProperties[] = 'unsigned';
|
||||
}
|
||||
|
||||
if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) {
|
||||
if ($column1->getLength() != $column2->getLength()) {
|
||||
$changedProperties[] = 'length';
|
||||
}
|
||||
|
||||
if ($column1->getFixed() != $column2->getFixed()) {
|
||||
$changedProperties[] = 'fixed';
|
||||
}
|
||||
}
|
||||
|
||||
if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) {
|
||||
if ($column1->getPrecision() != $column2->getPrecision()) {
|
||||
$changedProperties[] = 'precision';
|
||||
}
|
||||
if ($column1->getScale() != $column2->getScale()) {
|
||||
$changedProperties[] = 'scale';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->_checkColumnPlatformOptions AS $optionName) {
|
||||
if($column1->hasPlatformOption($optionName) && $column2->hasPlatformOption($optionName)) {
|
||||
if ($column1->getPlatformOption($optionName) != $column2->getPlatformOption($optionName)) {
|
||||
$changedProperties[] = $optionName;
|
||||
}
|
||||
} else if ($column1->hasPlatformOption($optionName) != $column2->hasPlatformOption($optionName)) {
|
||||
$changedProperties[] = $optionName;
|
||||
}
|
||||
}
|
||||
|
||||
return $changedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the difference between the indexes $index1 and $index2.
|
||||
*
|
||||
* Compares $index1 with $index2 and returns $index2 if there are any
|
||||
* differences or false in case there are no differences.
|
||||
*
|
||||
* @param Index $index1
|
||||
* @param Index $index2
|
||||
* @return bool
|
||||
*/
|
||||
public function diffIndex(Index $index1, Index $index2)
|
||||
{
|
||||
if($index1->isPrimary() != $index2->isPrimary()) {
|
||||
return true;
|
||||
}
|
||||
if($index1->isUnique() != $index2->isUnique()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for removed index fields in $index2
|
||||
$index1Columns = $index1->getColumns();
|
||||
for($i = 0; $i < count($index1Columns); $i++) {
|
||||
$indexColumn = $index1Columns[$i];
|
||||
if (!$index2->hasColumnAtPosition($indexColumn, $i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for new index fields in $index2
|
||||
$index2Columns = $index2->getColumns();
|
||||
for($i = 0; $i < count($index2Columns); $i++) {
|
||||
$indexColumn = $index2Columns[$i];
|
||||
if (!$index1->hasColumnAtPosition($indexColumn, $i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Marker interface for contraints
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
interface Constraint
|
||||
{
|
||||
public function getName();
|
||||
|
||||
public function getColumns();
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* IBM Db2 Schema Manager
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class DB2SchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
/**
|
||||
* Return a list of all tables in the current database
|
||||
*
|
||||
* Apparently creator is the schema not the user who created it:
|
||||
* {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listTableNames()
|
||||
{
|
||||
$sql = $this->_platform->getListTablesSQL();
|
||||
$sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')";
|
||||
|
||||
$tables = $this->_conn->fetchAll($sql);
|
||||
|
||||
return $this->_getPortableTablesList($tables);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Table Column Definition
|
||||
*
|
||||
* @param array $tableColumn
|
||||
* @return Column
|
||||
*/
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
$tableColumn = array_change_key_case($tableColumn, \CASE_LOWER);
|
||||
|
||||
$length = null;
|
||||
$fixed = null;
|
||||
$unsigned = false;
|
||||
$scale = false;
|
||||
$precision = false;
|
||||
|
||||
switch (strtolower($tableColumn['typename'])) {
|
||||
case 'smallint':
|
||||
case 'bigint':
|
||||
case 'integer':
|
||||
case 'time':
|
||||
case 'date':
|
||||
$type = strtolower($tableColumn['typename']);
|
||||
break;
|
||||
case 'varchar':
|
||||
$type = 'string';
|
||||
$length = $tableColumn['length'];
|
||||
$fixed = false;
|
||||
break;
|
||||
case 'character':
|
||||
$type = 'string';
|
||||
$length = $tableColumn['length'];
|
||||
$fixed = true;
|
||||
break;
|
||||
case 'clob':
|
||||
$type = 'text';
|
||||
$length = $tableColumn['length'];
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type = 'decimal';
|
||||
$scale = $tableColumn['scale'];
|
||||
$precision = $tableColumn['length'];
|
||||
break;
|
||||
case 'timestamp':
|
||||
$type = 'datetime';
|
||||
break;
|
||||
default:
|
||||
throw new \Doctrine\DBAL\DBALException("Unknown Type: ".$tableColumn['typename']);
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'length' => $length,
|
||||
'unsigned' => (bool)$unsigned,
|
||||
'fixed' => (bool)$fixed,
|
||||
'default' => ($tableColumn['default'] == "NULL") ? null : $tableColumn['default'],
|
||||
'notnull' => (bool) ($tableColumn['nulls'] == 'N'),
|
||||
'scale' => null,
|
||||
'precision' => null,
|
||||
'platformOptions' => array(),
|
||||
);
|
||||
|
||||
if ($scale !== null && $precision !== null) {
|
||||
$options['scale'] = $scale;
|
||||
$options['precision'] = $precision;
|
||||
}
|
||||
|
||||
return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||
}
|
||||
|
||||
protected function _getPortableTablesList($tables)
|
||||
{
|
||||
$tableNames = array();
|
||||
foreach ($tables AS $tableRow) {
|
||||
$tableRow = array_change_key_case($tableRow, \CASE_LOWER);
|
||||
$tableNames[] = $tableRow['name'];
|
||||
}
|
||||
return $tableNames;
|
||||
}
|
||||
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
{
|
||||
$tableIndexRows = array();
|
||||
$indexes = array();
|
||||
foreach($tableIndexes AS $indexKey => $data) {
|
||||
$data = array_change_key_case($data, \CASE_LOWER);
|
||||
$unique = ($data['uniquerule'] == "D") ? false : true;
|
||||
$primary = ($data['uniquerule'] == "P");
|
||||
|
||||
$indexName = strtolower($data['name']);
|
||||
if ($primary) {
|
||||
$keyName = 'primary';
|
||||
} else {
|
||||
$keyName = $indexName;
|
||||
}
|
||||
|
||||
$indexes[$keyName] = new Index($indexName, explode("+", ltrim($data['colnames'], '+')), $unique, $primary);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
||||
{
|
||||
$tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
|
||||
|
||||
$tableForeignKey['deleterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['deleterule']);
|
||||
$tableForeignKey['updaterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['updaterule']);
|
||||
|
||||
return new ForeignKeyConstraint(
|
||||
array_map('trim', (array)$tableForeignKey['fkcolnames']),
|
||||
$tableForeignKey['reftbname'],
|
||||
array_map('trim', (array)$tableForeignKey['pkcolnames']),
|
||||
$tableForeignKey['relname'],
|
||||
array(
|
||||
'onUpdate' => $tableForeignKey['updaterule'],
|
||||
'onDelete' => $tableForeignKey['deleterule'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getPortableForeignKeyRuleDef($def)
|
||||
{
|
||||
if ($def == "C") {
|
||||
return "CASCADE";
|
||||
} else if ($def == "N") {
|
||||
return "SET NULL";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
$view = array_change_key_case($view, \CASE_LOWER);
|
||||
// sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199
|
||||
//$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']);
|
||||
if (!is_resource($view['text'])) {
|
||||
$pos = strpos($view['text'], ' AS ');
|
||||
$sql = substr($view['text'], $pos+4);
|
||||
} else {
|
||||
$sql = '';
|
||||
}
|
||||
|
||||
return new View($view['name'], $sql);
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
|
||||
class ForeignKeyConstraint extends AbstractAsset implements Constraint
|
||||
{
|
||||
/**
|
||||
* @var Table
|
||||
*/
|
||||
protected $_localTable;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_localColumnNames;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_foreignTableName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_foreignColumnNames;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_cascade = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_options;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $localColumnNames
|
||||
* @param string $foreignTableName
|
||||
* @param array $foreignColumnNames
|
||||
* @param string $cascade
|
||||
* @param string|null $name
|
||||
*/
|
||||
public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name=null, array $options=array())
|
||||
{
|
||||
$this->_setName($name);
|
||||
$this->_localColumnNames = $localColumnNames;
|
||||
$this->_foreignTableName = $foreignTableName;
|
||||
$this->_foreignColumnNames = $foreignColumnNames;
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalTableName()
|
||||
{
|
||||
return $this->_localTable->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
*/
|
||||
public function setLocalTable(Table $table)
|
||||
{
|
||||
$this->_localTable = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLocalColumns()
|
||||
{
|
||||
return $this->_localColumnNames;
|
||||
}
|
||||
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->_localColumnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getForeignTableName()
|
||||
{
|
||||
return $this->_foreignTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getForeignColumns()
|
||||
{
|
||||
return $this->_foreignColumnNames;
|
||||
}
|
||||
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->_options[$name]);
|
||||
}
|
||||
|
||||
public function getOption($name)
|
||||
{
|
||||
return $this->_options[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreign Key onUpdate status
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function onUpdate()
|
||||
{
|
||||
return $this->_onEvent('onUpdate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreign Key onDelete status
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function onDelete()
|
||||
{
|
||||
return $this->_onEvent('onDelete');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
* @return string|null
|
||||
*/
|
||||
private function _onEvent($event)
|
||||
{
|
||||
if (isset($this->_options[$event])) {
|
||||
$onEvent = strtoupper($this->_options[$event]);
|
||||
if (!in_array($onEvent, array('NO ACTION', 'RESTRICT'))) {
|
||||
return $onEvent;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
|
||||
class Index extends AbstractAsset implements Constraint
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_columns;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_isUnique = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_isPrimary = false;
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @param array $column
|
||||
* @param bool $isUnique
|
||||
* @param bool $isPrimary
|
||||
*/
|
||||
public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false)
|
||||
{
|
||||
$isUnique = ($isPrimary)?true:$isUnique;
|
||||
|
||||
$this->_setName($indexName);
|
||||
$this->_isUnique = $isUnique;
|
||||
$this->_isPrimary = $isPrimary;
|
||||
|
||||
foreach($columns AS $column) {
|
||||
$this->_addColumn($column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $column
|
||||
*/
|
||||
protected function _addColumn($column)
|
||||
{
|
||||
if(is_string($column)) {
|
||||
$this->_columns[] = $column;
|
||||
} else {
|
||||
throw new \InvalidArgumentException("Expecting a string as Index Column");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isUnique()
|
||||
{
|
||||
return $this->_isUnique;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrimary()
|
||||
{
|
||||
return $this->_isPrimary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
* @param int $pos
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumnAtPosition($columnName, $pos=0)
|
||||
{
|
||||
$columnName = strtolower($columnName);
|
||||
$indexColumns = \array_map('strtolower', $this->getColumns());
|
||||
return \array_search($columnName, $indexColumns) === $pos;
|
||||
}
|
||||
}
|
@ -1,399 +0,0 @@
|
||||
<?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.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DBAL\Schema;
|
||||
|
||||
/**
|
||||
* xxx
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
class MsSqlSchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return void
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
$query = "CREATE DATABASE $name";
|
||||
if ($this->conn->options['database_device']) {
|
||||
$query.= ' ON '.$this->conn->options['database_device'];
|
||||
$query.= $this->conn->options['database_size'] ? '=' .
|
||||
$this->conn->options['database_size'] : '';
|
||||
}
|
||||
return $this->conn->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return void
|
||||
*/
|
||||
public function dropDatabase($name)
|
||||
{
|
||||
return $this->conn->standaloneQuery('DROP DATABASE ' . $name, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'name' => array(
|
||||
* 'length' => '20',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 20,
|
||||
* ),
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 1,
|
||||
* 'default' => 'M',
|
||||
* ),
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @return void
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
case 'add':
|
||||
break;
|
||||
case 'remove':
|
||||
break;
|
||||
case 'name':
|
||||
case 'rename':
|
||||
case 'change':
|
||||
default:
|
||||
throw SchemaException::alterTableChangeNotSupported($changeName);
|
||||
}
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if ( ! empty($changes['add']) && is_array($changes['add'])) {
|
||||
foreach ($changes['add'] as $fieldName => $field) {
|
||||
if ($query) {
|
||||
$query .= ', ';
|
||||
}
|
||||
$query .= 'ADD ' . $this->getDeclaration($fieldName, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($changes['remove']) && is_array($changes['remove'])) {
|
||||
foreach ($changes['remove'] as $fieldName => $field) {
|
||||
if ($query) {
|
||||
$query .= ', ';
|
||||
}
|
||||
$query .= 'DROP COLUMN ' . $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->conn->exec('ALTER TABLE ' . $name . ' ' . $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createSequence($seqName, $start = 1, $allocationSize = 1)
|
||||
{
|
||||
$seqcolName = 'seq_col';
|
||||
$query = 'CREATE TABLE ' . $seqName . ' (' . $seqcolName .
|
||||
' INT PRIMARY KEY CLUSTERED IDENTITY(' . $start . ', 1) NOT NULL)';
|
||||
|
||||
$res = $this->conn->exec($query);
|
||||
|
||||
if ($start == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$query = 'SET IDENTITY_INSERT ' . $sequenceName . ' ON ' .
|
||||
'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES ( ' . $start . ')';
|
||||
$res = $this->conn->exec($query);
|
||||
} catch (Exception $e) {
|
||||
$result = $this->conn->exec('DROP TABLE ' . $sequenceName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function drops an existing sequence
|
||||
*
|
||||
* @param string $seqName name of the sequence to be dropped
|
||||
* @return void
|
||||
*/
|
||||
public function dropSequenceSql($seqName)
|
||||
{
|
||||
return 'DROP TABLE ' . $seqName;
|
||||
}
|
||||
|
||||
/**
|
||||
* lists all database sequences
|
||||
*
|
||||
* @param string|null $database
|
||||
* @return array
|
||||
*/
|
||||
public function listSequences($database = null)
|
||||
{
|
||||
$query = "SELECT name FROM sysobjects WHERE xtype = 'U'";
|
||||
$tableNames = $this->conn->fetchColumn($query);
|
||||
|
||||
return array_map(array($this->conn->formatter, 'fixSequenceName'), $tableNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* lists table constraints
|
||||
*
|
||||
* @param string $table database table name
|
||||
* @return array
|
||||
*/
|
||||
public function listTableColumns($table)
|
||||
{
|
||||
$sql = 'EXEC sp_columns @table_name = ' . $table;
|
||||
$result = $this->conn->fetchAssoc($sql);
|
||||
$columns = array();
|
||||
|
||||
foreach ($result as $key => $val) {
|
||||
$val = array_change_key_case($val, CASE_LOWER);
|
||||
|
||||
if (strstr($val['type_name'], ' ')) {
|
||||
list($type, $identity) = explode(' ', $val['type_name']);
|
||||
} else {
|
||||
$type = $val['type_name'];
|
||||
$identity = '';
|
||||
}
|
||||
|
||||
if ($type == 'varchar') {
|
||||
$type .= '(' . $val['length'] . ')';
|
||||
}
|
||||
|
||||
$val['type'] = $type;
|
||||
$val['identity'] = $identity;
|
||||
$decl = $this->conn->getDatabasePlatform()->getPortableDeclaration($val);
|
||||
|
||||
$description = array(
|
||||
'name' => $val['column_name'],
|
||||
'ntype' => $type,
|
||||
'type' => $decl['type'][0],
|
||||
'alltypes' => $decl['type'],
|
||||
'length' => $decl['length'],
|
||||
'fixed' => $decl['fixed'],
|
||||
'unsigned' => $decl['unsigned'],
|
||||
'notnull' => (bool) (trim($val['is_nullable']) === 'NO'),
|
||||
'default' => $val['column_def'],
|
||||
'primary' => (strtolower($identity) == 'identity'),
|
||||
);
|
||||
$columns[$val['column_name']] = $description;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* lists table constraints
|
||||
*
|
||||
* @param string $table database table name
|
||||
* @return array
|
||||
*/
|
||||
public function listTableIndexes($table)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* lists tables
|
||||
*
|
||||
* @param string|null $database
|
||||
* @return array
|
||||
*/
|
||||
public function listTables($database = null)
|
||||
{
|
||||
$sql = "SELECT name FROM sysobjects WHERE type = 'U' AND name <> 'dtproperties' ORDER BY name";
|
||||
|
||||
return $this->conn->fetchColumn($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* lists all triggers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listTriggers($database = null)
|
||||
{
|
||||
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR'";
|
||||
|
||||
$result = $this->conn->fetchColumn($query);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* lists table triggers
|
||||
*
|
||||
* @param string $table database table name
|
||||
* @return array
|
||||
*/
|
||||
public function listTableTriggers($table)
|
||||
{
|
||||
$table = $this->conn->quote($table, 'text');
|
||||
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR' AND object_name(parent_obj) = " . $table;
|
||||
|
||||
$result = $this->conn->fetchColumn($query);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* lists table views
|
||||
*
|
||||
* @param string $table database table name
|
||||
* @return array
|
||||
*/
|
||||
public function listTableViews($table)
|
||||
{
|
||||
$keyName = 'INDEX_NAME';
|
||||
$pkName = 'PK_NAME';
|
||||
if ($this->conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) {
|
||||
if ($this->conn->getAttribute(Doctrine::ATTR_FIELD_CASE) == CASE_LOWER) {
|
||||
$keyName = strtolower($keyName);
|
||||
$pkName = strtolower($pkName);
|
||||
} else {
|
||||
$keyName = strtoupper($keyName);
|
||||
$pkName = strtoupper($pkName);
|
||||
}
|
||||
}
|
||||
$table = $this->conn->quote($table, 'text');
|
||||
$query = 'EXEC sp_statistics @table_name = ' . $table;
|
||||
$indexes = $this->conn->fetchColumn($query, $keyName);
|
||||
|
||||
$query = 'EXEC sp_pkeys @table_name = ' . $table;
|
||||
$pkAll = $this->conn->fetchColumn($query, $pkName);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
if ( ! in_array($index, $pkAll) && $index != null) {
|
||||
$result[] = $this->conn->formatter->fixIndexName($index);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* lists database views
|
||||
*
|
||||
* @param string|null $database
|
||||
* @return array
|
||||
*/
|
||||
public function listViews($database = null)
|
||||
{
|
||||
$query = "SELECT name FROM sysobjects WHERE xtype = 'V'";
|
||||
|
||||
return $this->conn->fetchColumn($query);
|
||||
}
|
||||
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
}
|
@ -1,272 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Schema manager for the MySql RDBMS.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
class MySqlSchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']);
|
||||
}
|
||||
|
||||
protected function _getPortableTableDefinition($table)
|
||||
{
|
||||
return array_shift($table);
|
||||
}
|
||||
|
||||
protected function _getPortableUserDefinition($user)
|
||||
{
|
||||
return array(
|
||||
'user' => $user['User'],
|
||||
'password' => $user['Password'],
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
{
|
||||
foreach($tableIndexes AS $k => $v) {
|
||||
$v = array_change_key_case($v, CASE_LOWER);
|
||||
if($v['key_name'] == 'PRIMARY') {
|
||||
$v['primary'] = true;
|
||||
} else {
|
||||
$v['primary'] = false;
|
||||
}
|
||||
$tableIndexes[$k] = $v;
|
||||
}
|
||||
|
||||
return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
|
||||
}
|
||||
|
||||
protected function _getPortableSequenceDefinition($sequence)
|
||||
{
|
||||
return end($sequence);
|
||||
}
|
||||
|
||||
protected function _getPortableDatabaseDefinition($database)
|
||||
{
|
||||
return $database['Database'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a portable column definition.
|
||||
*
|
||||
* The database type is mapped to a corresponding Doctrine mapping type.
|
||||
*
|
||||
* @param $tableColumn
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
$dbType = strtolower($tableColumn['Type']);
|
||||
$dbType = strtok($dbType, '(), ');
|
||||
if ($dbType == 'national') {
|
||||
$dbType = strtok('(), ');
|
||||
}
|
||||
if (isset($tableColumn['length'])) {
|
||||
$length = $tableColumn['length'];
|
||||
$decimal = '';
|
||||
} else {
|
||||
$length = strtok('(), ');
|
||||
$decimal = strtok('(), ') ? strtok('(), '):null;
|
||||
}
|
||||
$type = array();
|
||||
$unsigned = $fixed = null;
|
||||
|
||||
if ( ! isset($tableColumn['name'])) {
|
||||
$tableColumn['name'] = '';
|
||||
}
|
||||
|
||||
$scale = null;
|
||||
$precision = null;
|
||||
|
||||
// Map db type to Doctrine mapping type
|
||||
switch ($dbType) {
|
||||
case 'tinyint':
|
||||
$type = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type = 'smallint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'mediumint':
|
||||
$type = 'integer';
|
||||
$length = null;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
$type = 'integer';
|
||||
$length = null;
|
||||
break;
|
||||
case 'bigint':
|
||||
$type = 'bigint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
$type = 'text';
|
||||
$fixed = false;
|
||||
break;
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'string':
|
||||
case 'char':
|
||||
$type = 'string';
|
||||
if ($length == '1') {
|
||||
$type = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} else if (strstr($dbType, 'text')) {
|
||||
$type = 'text';
|
||||
if ($decimal == 'binary') {
|
||||
$type = 'blob';
|
||||
}
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'set':
|
||||
$fixed = false;
|
||||
$type = 'text';
|
||||
$type = 'integer'; //FIXME:???
|
||||
break;
|
||||
case 'date':
|
||||
$type = 'date';
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type = 'datetime';
|
||||
break;
|
||||
case 'time':
|
||||
$type = 'time';
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
case 'decimal':
|
||||
if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['Type'], $match)) {
|
||||
$precision = $match[1];
|
||||
$scale = $match[2];
|
||||
$length = null;
|
||||
}
|
||||
$type = 'decimal';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
case 'binary':
|
||||
case 'varbinary':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type = 'integer';
|
||||
$type = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'geometry':
|
||||
case 'geometrycollection':
|
||||
case 'point':
|
||||
case 'multipoint':
|
||||
case 'linestring':
|
||||
case 'multilinestring':
|
||||
case 'polygon':
|
||||
case 'multipolygon':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$type = 'string';
|
||||
$length = null;
|
||||
}
|
||||
|
||||
$length = ((int) $length == 0) ? null : (int) $length;
|
||||
$def = array(
|
||||
'type' => $type,
|
||||
'length' => $length,
|
||||
'unsigned' => (bool) $unsigned,
|
||||
'fixed' => (bool) $fixed
|
||||
);
|
||||
|
||||
$options = array(
|
||||
'length' => $length,
|
||||
'unsigned' => (bool)$unsigned,
|
||||
'fixed' => (bool)$fixed,
|
||||
'default' => $tableColumn['Default'],
|
||||
'notnull' => (bool) ($tableColumn['Null'] != 'YES'),
|
||||
'scale' => null,
|
||||
'precision' => null,
|
||||
'platformOptions' => array(
|
||||
'primary' => (strtolower($tableColumn['Key']) == 'pri') ? true : false,
|
||||
'unique' => (strtolower($tableColumn['Key']) == 'uni') ? true :false,
|
||||
'autoincrement' => (bool) (strpos($tableColumn['Extra'], 'auto_increment') !== false),
|
||||
),
|
||||
);
|
||||
|
||||
if ($scale !== null && $precision !== null) {
|
||||
$options['scale'] = $scale;
|
||||
$options['precision'] = $precision;
|
||||
}
|
||||
|
||||
return new Column($tableColumn['Field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||
}
|
||||
|
||||
public function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
||||
{
|
||||
$tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
|
||||
|
||||
if (!isset($tableForeignKey['delete_rule']) || $tableForeignKey['delete_rule'] == "RESTRICT") {
|
||||
$tableForeignKey['delete_rule'] = null;
|
||||
}
|
||||
if (!isset($tableForeignKey['update_rule']) || $tableForeignKey['update_rule'] == "RESTRICT") {
|
||||
$tableForeignKey['update_rule'] = null;
|
||||
}
|
||||
|
||||
return new ForeignKeyConstraint(
|
||||
(array)$tableForeignKey['column_name'],
|
||||
$tableForeignKey['referenced_table_name'],
|
||||
(array)$tableForeignKey['referenced_column_name'],
|
||||
$tableForeignKey['constraint_name'],
|
||||
array(
|
||||
'onUpdate' => $tableForeignKey['update_rule'],
|
||||
'onDelete' => $tableForeignKey['delete_rule'],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
<?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.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DBAL\Schema;
|
||||
|
||||
/**
|
||||
* Oracle Schema Manager
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
class OracleSchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
$view = \array_change_key_case($view, CASE_LOWER);
|
||||
|
||||
return new View($view['view_name'], $view['text']);
|
||||
}
|
||||
|
||||
protected function _getPortableUserDefinition($user)
|
||||
{
|
||||
$user = \array_change_key_case($user, CASE_LOWER);
|
||||
|
||||
return array(
|
||||
'user' => $user['username'],
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getPortableTableDefinition($table)
|
||||
{
|
||||
$table = \array_change_key_case($table, CASE_LOWER);
|
||||
|
||||
return $table['table_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @license New BSD License
|
||||
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
|
||||
* @param array $tableIndexes
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
{
|
||||
$indexBuffer = array();
|
||||
foreach ( $tableIndexes as $tableIndex ) {
|
||||
$tableIndex = \array_change_key_case($tableIndex, CASE_LOWER);
|
||||
|
||||
$keyName = strtolower($tableIndex['name']);
|
||||
|
||||
if ( strtolower($tableIndex['is_primary']) == "p" ) {
|
||||
$keyName = 'primary';
|
||||
$buffer['primary'] = true;
|
||||
$buffer['non_unique'] = false;
|
||||
} else {
|
||||
$buffer['primary'] = false;
|
||||
$buffer['non_unique'] = ( $tableIndex['is_unique'] == 0 ) ? true : false;
|
||||
}
|
||||
$buffer['key_name'] = $keyName;
|
||||
$buffer['column_name'] = $tableIndex['column_name'];
|
||||
$indexBuffer[] = $buffer;
|
||||
}
|
||||
return parent::_getPortableTableIndexesList($indexBuffer, $tableName);
|
||||
}
|
||||
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
$tableColumn = \array_change_key_case($tableColumn, CASE_LOWER);
|
||||
|
||||
$dbType = strtolower($tableColumn['data_type']);
|
||||
if(strpos($dbType, "timestamp(") === 0) {
|
||||
$dbType = "timestamp";
|
||||
}
|
||||
|
||||
$type = array();
|
||||
$length = $unsigned = $fixed = null;
|
||||
if ( ! empty($tableColumn['data_length'])) {
|
||||
$length = $tableColumn['data_length'];
|
||||
}
|
||||
|
||||
if ( ! isset($tableColumn['column_name'])) {
|
||||
$tableColumn['column_name'] = '';
|
||||
}
|
||||
|
||||
if (stripos($tableColumn['data_default'], 'NULL') !== null) {
|
||||
$tableColumn['data_default'] = null;
|
||||
}
|
||||
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
switch ($dbType) {
|
||||
case 'integer':
|
||||
case 'number':
|
||||
if($tableColumn['data_scale'] > 0) {
|
||||
$type = 'decimal';
|
||||
$precision = $tableColumn['data_precision'];
|
||||
$scale = $tableColumn['data_scale'];
|
||||
} else {
|
||||
$type = 'integer';
|
||||
}
|
||||
$length = null;
|
||||
break;
|
||||
case 'pls_integer':
|
||||
case 'binary_integer':
|
||||
$type = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'varchar':
|
||||
case 'varchar2':
|
||||
case 'nvarchar2':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
case 'nchar':
|
||||
if ($length == '1' && preg_match('/^(is|has)/', $tableColumn['column_name'])) {
|
||||
$type = 'boolean';
|
||||
} else {
|
||||
$type = 'string';
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
case 'timestamp':
|
||||
$type = 'datetime';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
$precision = $tableColumn['data_precision'];
|
||||
$scale = $tableColumn['data_scale'];
|
||||
$type = 'decimal';
|
||||
$length = null;
|
||||
break;
|
||||
case 'long':
|
||||
$type = 'string';
|
||||
case 'clob':
|
||||
case 'nclob':
|
||||
$length = null;
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'blob':
|
||||
case 'raw':
|
||||
case 'long raw':
|
||||
case 'bfile':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'rowid':
|
||||
case 'urowid':
|
||||
default:
|
||||
$type = 'string';
|
||||
$length = null;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'notnull' => (bool) ($tableColumn['nullable'] === 'N'),
|
||||
'fixed' => (bool) $fixed,
|
||||
'unsigned' => (bool) $unsigned,
|
||||
'default' => $tableColumn['data_default'],
|
||||
'length' => $length,
|
||||
'precision' => $precision,
|
||||
'scale' => $scale,
|
||||
'platformDetails' => array(),
|
||||
);
|
||||
|
||||
return new Column($tableColumn['column_name'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||
}
|
||||
|
||||
protected function _getPortableTableForeignKeysList($tableForeignKeys)
|
||||
{
|
||||
$list = array();
|
||||
foreach ($tableForeignKeys as $key => $value) {
|
||||
$value = \array_change_key_case($value, CASE_LOWER);
|
||||
if (!isset($list[$value['constraint_name']])) {
|
||||
if ($value['delete_rule'] == "NO ACTION") {
|
||||
$value['delete_rule'] = null;
|
||||
}
|
||||
|
||||
$list[$value['constraint_name']] = array(
|
||||
'name' => $value['constraint_name'],
|
||||
'local' => array(),
|
||||
'foreign' => array(),
|
||||
'foreignTable' => $value['references_table'],
|
||||
'onDelete' => $value['delete_rule'],
|
||||
);
|
||||
}
|
||||
$list[$value['constraint_name']]['local'][$value['position']] = $value['local_column'];
|
||||
$list[$value['constraint_name']]['foreign'][$value['position']] = $value['foreign_column'];
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach($list AS $constraint) {
|
||||
$result[] = new ForeignKeyConstraint(
|
||||
array_values($constraint['local']), $constraint['foreignTable'],
|
||||
array_values($constraint['foreign']), $constraint['name'],
|
||||
array('onDelete' => $constraint['onDelete'])
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function _getPortableSequenceDefinition($sequence)
|
||||
{
|
||||
$sequence = \array_change_key_case($sequence, CASE_LOWER);
|
||||
return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['min_value']);
|
||||
}
|
||||
|
||||
protected function _getPortableFunctionDefinition($function)
|
||||
{
|
||||
$function = \array_change_key_case($function, CASE_LOWER);
|
||||
return $function['name'];
|
||||
}
|
||||
|
||||
protected function _getPortableDatabaseDefinition($database)
|
||||
{
|
||||
$database = \array_change_key_case($database, CASE_LOWER);
|
||||
return $database['username'];
|
||||
}
|
||||
|
||||
public function createDatabase($database = null)
|
||||
{
|
||||
if (is_null($database)) {
|
||||
$database = $this->_conn->getDatabase();
|
||||
}
|
||||
|
||||
$params = $this->_conn->getParams();
|
||||
$username = $database;
|
||||
$password = $params['password'];
|
||||
|
||||
$query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
|
||||
$result = $this->_conn->executeUpdate($query);
|
||||
|
||||
$query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username;
|
||||
$result = $this->_conn->executeUpdate($query);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dropAutoincrement($table)
|
||||
{
|
||||
$sql = $this->_platform->getDropAutoincrementSql($table);
|
||||
foreach ($sql as $query) {
|
||||
$this->_conn->executeUpdate($query);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dropTable($name)
|
||||
{
|
||||
$this->dropAutoincrement($name);
|
||||
|
||||
return parent::dropTable($name);
|
||||
}
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* xxx
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
class PostgreSqlSchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
||||
{
|
||||
$onUpdate = null;
|
||||
$onDelete = null;
|
||||
|
||||
if(preg_match('(ON UPDATE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
|
||||
$onUpdate = $match[1];
|
||||
}
|
||||
if(preg_match('(ON DELETE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
|
||||
$onDelete = $match[1];
|
||||
}
|
||||
|
||||
if(preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) {
|
||||
$localColumns = explode(",", $values[1]);
|
||||
$foreignColumns = explode(",", $values[3]);
|
||||
$foreignTable = $values[2];
|
||||
}
|
||||
|
||||
return new ForeignKeyConstraint(
|
||||
$localColumns, $foreignTable, $foreignColumns, $tableForeignKey['conname'],
|
||||
array('onUpdate' => $onUpdate, 'onDelete' => $onDelete)
|
||||
);
|
||||
}
|
||||
|
||||
public function dropDatabase($database)
|
||||
{
|
||||
$params = $this->_conn->getParams();
|
||||
$params["dbname"] = "postgres";
|
||||
$tmpPlatform = $this->_platform;
|
||||
$tmpConn = $this->_conn;
|
||||
|
||||
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
|
||||
$this->_platform = $this->_conn->getDatabasePlatform();
|
||||
|
||||
parent::dropDatabase($database);
|
||||
|
||||
$this->_platform = $tmpPlatform;
|
||||
$this->_conn = $tmpConn;
|
||||
}
|
||||
|
||||
public function createDatabase($database)
|
||||
{
|
||||
$params = $this->_conn->getParams();
|
||||
$params["dbname"] = "postgres";
|
||||
$tmpPlatform = $this->_platform;
|
||||
$tmpConn = $this->_conn;
|
||||
|
||||
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
|
||||
$this->_platform = $this->_conn->getDatabasePlatform();
|
||||
|
||||
parent::createDatabase($database);
|
||||
|
||||
$this->_platform = $tmpPlatform;
|
||||
$this->_conn = $tmpConn;
|
||||
}
|
||||
|
||||
protected function _getPortableTriggerDefinition($trigger)
|
||||
{
|
||||
return $trigger['trigger_name'];
|
||||
}
|
||||
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
return new View($view['viewname'], $view['definition']);
|
||||
}
|
||||
|
||||
protected function _getPortableUserDefinition($user)
|
||||
{
|
||||
return array(
|
||||
'user' => $user['usename'],
|
||||
'password' => $user['passwd']
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getPortableTableDefinition($table)
|
||||
{
|
||||
return $table['table_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @license New BSD License
|
||||
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
|
||||
* @param array $tableIndexes
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
{
|
||||
$buffer = array();
|
||||
foreach($tableIndexes AS $row) {
|
||||
$colNumbers = explode( ' ', $row['indkey'] );
|
||||
$colNumbersSql = 'IN (' . join( ' ,', $colNumbers ) . ' )';
|
||||
$columnNameSql = "SELECT attnum, attname FROM pg_attribute
|
||||
WHERE attrelid={$row['indrelid']} AND attnum $colNumbersSql ORDER BY attnum ASC;";
|
||||
|
||||
$stmt = $this->_conn->executeQuery($columnNameSql);
|
||||
$indexColumns = $stmt->fetchAll();
|
||||
|
||||
// required for getting the order of the columns right.
|
||||
foreach ($colNumbers AS $colNum) {
|
||||
foreach ( $indexColumns as $colRow ) {
|
||||
if ($colNum == $colRow['attnum']) {
|
||||
$buffer[] = array(
|
||||
'key_name' => $row['relname'],
|
||||
'column_name' => $colRow['attname'],
|
||||
'non_unique' => !$row['indisunique'],
|
||||
'primary' => $row['indisprimary']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent::_getPortableTableIndexesList($buffer);
|
||||
}
|
||||
|
||||
protected function _getPortableDatabaseDefinition($database)
|
||||
{
|
||||
return $database['datname'];
|
||||
}
|
||||
|
||||
protected function _getPortableSequenceDefinition($sequence)
|
||||
{
|
||||
$data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM '.$sequence['relname']);
|
||||
return new Sequence($sequence['relname'], $data[0]['increment_by'], $data[0]['min_value']);
|
||||
}
|
||||
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
$tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
|
||||
|
||||
if (strtolower($tableColumn['type']) === 'varchar') {
|
||||
// get length from varchar definition
|
||||
$length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']);
|
||||
$tableColumn['length'] = $length;
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
|
||||
if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches)) {
|
||||
$tableColumn['sequence'] = $matches[1];
|
||||
$tableColumn['default'] = null;
|
||||
}
|
||||
|
||||
if (stripos($tableColumn['default'], 'NULL') !== null) {
|
||||
$tableColumn['default'] = null;
|
||||
}
|
||||
|
||||
$length = (isset($tableColumn['length'])) ? $tableColumn['length'] : null;
|
||||
if ($length == '-1' && isset($tableColumn['atttypmod'])) {
|
||||
$length = $tableColumn['atttypmod'] - 4;
|
||||
}
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
$type = array();
|
||||
$fixed = null;
|
||||
|
||||
if ( ! isset($tableColumn['name'])) {
|
||||
$tableColumn['name'] = '';
|
||||
}
|
||||
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
$dbType = strtolower($tableColumn['type']);
|
||||
|
||||
$autoincrement = false;
|
||||
switch ($dbType) {
|
||||
case 'smallint':
|
||||
case 'int2':
|
||||
$type = 'smallint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'serial':
|
||||
case 'serial4':
|
||||
$autoincrement = true;
|
||||
// break missing intentionally
|
||||
case 'int':
|
||||
case 'int4':
|
||||
case 'integer':
|
||||
$type = 'integer';
|
||||
$length = null;
|
||||
break;
|
||||
case 'bigserial':
|
||||
case 'serial8':
|
||||
$autoincrement = true;
|
||||
// break missing intentionally
|
||||
case 'bigint':
|
||||
case 'int8':
|
||||
$type = 'bigint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
$type = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'text':
|
||||
$fixed = false;
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'varchar':
|
||||
case 'interval':
|
||||
case '_varchar':
|
||||
$fixed = false;
|
||||
case 'tsvector':
|
||||
case 'unknown':
|
||||
case 'char':
|
||||
case 'bpchar':
|
||||
$type = 'string';
|
||||
if ($length == '1') {
|
||||
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
|
||||
$type = 'boolean';
|
||||
}
|
||||
} elseif (strstr($dbType, 'text')) {
|
||||
$type = 'text';
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
case 'timetz':
|
||||
case 'timestamptz':
|
||||
$type = 'datetime';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'float4':
|
||||
case 'float8':
|
||||
case 'double':
|
||||
case 'double precision':
|
||||
case 'real':
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
case 'numeric':
|
||||
if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) {
|
||||
$precision = $match[1];
|
||||
$scale = $match[2];
|
||||
$length = null;
|
||||
}
|
||||
$type = 'decimal';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
case 'bytea':
|
||||
case 'geometry':
|
||||
case 'geometrycollection':
|
||||
case 'point':
|
||||
case 'multipoint':
|
||||
case 'linestring':
|
||||
case 'multilinestring':
|
||||
case 'polygon':
|
||||
case 'multipolygon':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'oid':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'length' => $length,
|
||||
'notnull' => (bool) $tableColumn['isnotnull'],
|
||||
'default' => $tableColumn['default'],
|
||||
'primary' => (bool) ($tableColumn['pri'] == 't'),
|
||||
'precision' => $precision,
|
||||
'scale' => $scale,
|
||||
'fixed' => $fixed,
|
||||
'unsigned' => false,
|
||||
'platformDetails' => array(
|
||||
'autoincrement' => $autoincrement,
|
||||
),
|
||||
);
|
||||
|
||||
return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||
}
|
||||
}
|
@ -1,327 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor\CreateSchemaSqlCollector;
|
||||
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
|
||||
/**
|
||||
* Object representation of a database schema
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Schema extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_tables = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_sequences = array();
|
||||
|
||||
/**
|
||||
* @var SchemaConfig
|
||||
*/
|
||||
protected $_schemaConfig = false;
|
||||
|
||||
/**
|
||||
* @param array $tables
|
||||
* @param array $sequences
|
||||
* @param array $views
|
||||
* @param array $triggers
|
||||
* @param SchemaConfig $schemaConfig
|
||||
*/
|
||||
public function __construct(array $tables=array(), array $sequences=array(), SchemaConfig $schemaConfig=null)
|
||||
{
|
||||
if ($schemaConfig == null) {
|
||||
$schemaConfig = new SchemaConfig();
|
||||
}
|
||||
$this->_schemaConfig = $schemaConfig;
|
||||
|
||||
foreach ($tables AS $table) {
|
||||
$this->_addTable($table);
|
||||
}
|
||||
foreach ($sequences AS $sequence) {
|
||||
$this->_addSequence($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasExplicitForeignKeyIndexes()
|
||||
{
|
||||
return $this->_schemaConfig->hasExplicitForeignKeyIndexes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
*/
|
||||
protected function _addTable(Table $table)
|
||||
{
|
||||
$tableName = strtolower($table->getName());
|
||||
if(isset($this->_tables[$tableName])) {
|
||||
throw SchemaException::tableAlreadyExists($tableName);
|
||||
}
|
||||
|
||||
$this->_tables[$tableName] = $table;
|
||||
$table->setSchemaConfig($this->_schemaConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
protected function _addSequence(Sequence $sequence)
|
||||
{
|
||||
$seqName = strtolower($sequence->getName());
|
||||
if (isset($this->_sequences[$seqName])) {
|
||||
throw SchemaException::sequenceAlreadyExists($seqName);
|
||||
}
|
||||
$this->_sequences[$seqName] = $sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tables of this schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->_tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return Table
|
||||
*/
|
||||
public function getTable($tableName)
|
||||
{
|
||||
$tableName = strtolower($tableName);
|
||||
if (!isset($this->_tables[$tableName])) {
|
||||
throw SchemaException::tableDoesNotExist($tableName);
|
||||
}
|
||||
|
||||
return $this->_tables[$tableName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this schema have a table with the given name?
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
$tableName = strtolower($tableName);
|
||||
return isset($this->_tables[$tableName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSequence($sequenceName)
|
||||
{
|
||||
$sequenceName = strtolower($sequenceName);
|
||||
return isset($this->_sequences[$sequenceName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SchemaException
|
||||
* @param string $sequenceName
|
||||
* @return Doctrine\DBAL\Schema\Sequence
|
||||
*/
|
||||
public function getSequence($sequenceName)
|
||||
{
|
||||
$sequenceName = strtolower($sequenceName);
|
||||
if(!$this->hasSequence($sequenceName)) {
|
||||
throw SchemaException::sequenceDoesNotExist($sequenceName);
|
||||
}
|
||||
return $this->_sequences[$sequenceName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\DBAL\Schema\Sequence[]
|
||||
*/
|
||||
public function getSequences()
|
||||
{
|
||||
return $this->_sequences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new table
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Table
|
||||
*/
|
||||
public function createTable($tableName)
|
||||
{
|
||||
$table = new Table($tableName);
|
||||
$this->_addTable($table);
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a table
|
||||
*
|
||||
* @param string $oldTableName
|
||||
* @param string $newTableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function renameTable($oldTableName, $newTableName)
|
||||
{
|
||||
$table = $this->getTable($oldTableName);
|
||||
$table->_setName($newTableName);
|
||||
|
||||
$this->dropTable($oldTableName);
|
||||
$this->_addTable($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a table from the schema.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return Schema
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
$tableName = strtolower($tableName);
|
||||
$table = $this->getTable($tableName);
|
||||
unset($this->_tables[$tableName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sequence
|
||||
*
|
||||
* @param string $sequenceName
|
||||
* @param int $allocationSize
|
||||
* @param int $initialValue
|
||||
* @return Sequence
|
||||
*/
|
||||
public function createSequence($sequenceName, $allocationSize=1, $initialValue=1)
|
||||
{
|
||||
$seq = new Sequence($sequenceName, $allocationSize, $initialValue);
|
||||
$this->_addSequence($seq);
|
||||
return $seq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return Schema
|
||||
*/
|
||||
public function dropSequence($sequenceName)
|
||||
{
|
||||
$sequenceName = strtolower($sequenceName);
|
||||
unset($this->_sequences[$sequenceName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of necessary sql queries to create the schema on the given platform.
|
||||
*
|
||||
* @param AbstractPlatform $platform
|
||||
* @return array
|
||||
*/
|
||||
public function toSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
$sqlCollector = new CreateSchemaSqlCollector($platform);
|
||||
$this->visit($sqlCollector);
|
||||
|
||||
return $sqlCollector->getQueries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of necessary sql queries to drop the schema on the given platform.
|
||||
*
|
||||
* @param AbstractPlatform $platform
|
||||
* @return array
|
||||
*/
|
||||
public function toDropSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
$dropSqlCollector = new DropSchemaSqlCollector($platform);
|
||||
$this->visit($dropSqlCollector);
|
||||
|
||||
return $dropSqlCollector->getQueries();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $toSchema
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function getMigrateToSql(Schema $toSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
$comparator = new Comparator();
|
||||
$schemaDiff = $comparator->compare($this, $toSchema);
|
||||
return $schemaDiff->toSql($platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $fromSchema
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function getMigrateFromSql(Schema $fromSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
$comparator = new Comparator();
|
||||
$schemaDiff = $comparator->compare($fromSchema, $this);
|
||||
return $schemaDiff->toSql($platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptSchema($this);
|
||||
|
||||
foreach ($this->_tables AS $table) {
|
||||
$table->visit($visitor);
|
||||
}
|
||||
foreach ($this->_sequences AS $sequence) {
|
||||
$sequence->visit($visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning a Schema triggers a deep clone of all related assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->_tables AS $k => $table) {
|
||||
$this->_tables[$k] = clone $table;
|
||||
}
|
||||
foreach ($this->_sequences AS $k => $sequence) {
|
||||
$this->_sequences[$k] = clone $sequence;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Schema.php 6876 2009-12-06 23:11:35Z beberlei $
|
||||
*
|
||||
* 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\Schema;
|
||||
|
||||
/**
|
||||
* Configuration for a Schema
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class SchemaConfig
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_hasExplicitForeignKeyIndexes = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_maxIdentifierLength = 63;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasExplicitForeignKeyIndexes()
|
||||
{
|
||||
return $this->_hasExplicitForeignKeyIndexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*/
|
||||
public function setExplicitForeignKeyIndexes($flag)
|
||||
{
|
||||
$this->_hasExplicitForeignKeyIndexes = (bool)$flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*/
|
||||
public function setMaxIdentifierLength($length)
|
||||
{
|
||||
$this->_maxIdentifierLength = (int)$length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxIdentifierLength()
|
||||
{
|
||||
return $this->_maxIdentifierLength;
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use \Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* Schema Diff
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class SchemaDiff
|
||||
{
|
||||
/**
|
||||
* All added tables
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaTable)
|
||||
*/
|
||||
public $newTables = array();
|
||||
|
||||
/**
|
||||
* All changed tables
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaTableDiff)
|
||||
*/
|
||||
public $changedTables = array();
|
||||
|
||||
/**
|
||||
* All removed tables
|
||||
*
|
||||
* @var array(string=>Table)
|
||||
*/
|
||||
public $removedTables = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $newSequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $changedSequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $removedSequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $orphanedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* Constructs an SchemaDiff object.
|
||||
*
|
||||
* @param array(string=>Table) $newTables
|
||||
* @param array(string=>TableDiff) $changedTables
|
||||
* @param array(string=>bool) $removedTables
|
||||
*/
|
||||
public function __construct( $newTables = array(), $changedTables = array(), $removedTables = array() )
|
||||
{
|
||||
$this->newTables = $newTables;
|
||||
$this->changedTables = $changedTables;
|
||||
$this->removedTables = $removedTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* The to save sql mode ensures that the following things don't happen:
|
||||
*
|
||||
* 1. Tables are deleted
|
||||
* 2. Sequences are deleted
|
||||
* 3. Foreign Keys which reference tables that would otherwise be deleted.
|
||||
*
|
||||
* This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all.
|
||||
*
|
||||
* @param AbstractPlatform $platform
|
||||
* @return array
|
||||
*/
|
||||
public function toSaveSql(AbstractPlatform $platform)
|
||||
{
|
||||
return $this->_toSql($platform, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
* @return array
|
||||
*/
|
||||
public function toSql(AbstractPlatform $platform)
|
||||
{
|
||||
return $this->_toSql($platform, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
* @param bool $saveMode
|
||||
* @return array
|
||||
*/
|
||||
protected function _toSql(AbstractPlatform $platform, $saveMode = false)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ($platform->supportsForeignKeyConstraints() && $saveMode == false) {
|
||||
foreach ($this->orphanedForeignKeys AS $orphanedForeignKey) {
|
||||
$sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTableName());
|
||||
}
|
||||
}
|
||||
|
||||
if ($platform->supportsSequences() == true) {
|
||||
foreach ($this->changedSequences AS $sequence) {
|
||||
$sql[] = $platform->getDropSequenceSQL($sequence);
|
||||
$sql[] = $platform->getCreateSequenceSQL($sequence);
|
||||
}
|
||||
|
||||
if ($saveMode === false) {
|
||||
foreach ($this->removedSequences AS $sequence) {
|
||||
$sql[] = $platform->getDropSequenceSQL($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->newSequences AS $sequence) {
|
||||
$sql[] = $platform->getCreateSequenceSQL($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
$foreignKeySql = array();
|
||||
foreach ($this->newTables AS $table) {
|
||||
$sql = array_merge(
|
||||
$sql,
|
||||
$platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
|
||||
);
|
||||
foreach ($table->getForeignKeys() AS $foreignKey) {
|
||||
$foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
|
||||
}
|
||||
}
|
||||
$sql = array_merge($sql, $foreignKeySql);
|
||||
|
||||
if ($saveMode === false) {
|
||||
foreach ($this->removedTables AS $table) {
|
||||
$sql[] = $platform->getDropTableSQL($table);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->changedTables AS $tableDiff) {
|
||||
$sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Schema;
|
||||
|
||||
class SchemaException extends \Doctrine\DBAL\DBALException
|
||||
{
|
||||
const TABLE_DOESNT_EXIST = 10;
|
||||
const TABLE_ALREADY_EXISTS = 20;
|
||||
const COLUMN_DOESNT_EXIST = 30;
|
||||
const COLUMN_ALREADY_EXISTS = 40;
|
||||
const INDEX_DOESNT_EXIST = 50;
|
||||
const INDEX_ALREADY_EXISTS = 60;
|
||||
const SEQUENCE_DOENST_EXIST = 70;
|
||||
const SEQUENCE_ALREADY_EXISTS = 80;
|
||||
const INDEX_INVALID_NAME = 90;
|
||||
const FOREIGNKEY_DOESNT_EXIST = 100;
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function tableDoesNotExist($tableName)
|
||||
{
|
||||
return new self("There is no table with name '".$tableName."' in the schema.", self::TABLE_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexNameInvalid($indexName)
|
||||
{
|
||||
return new self("Invalid index-name $indexName given, has to be [a-zA-Z0-9_]", self::INDEX_INVALID_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexDoesNotExist($indexName)
|
||||
{
|
||||
return new self("Index '".$indexName."' does not exist.", self::INDEX_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function indexAlreadyExists($indexName)
|
||||
{
|
||||
return new self("An index with name $indexName was already defined.", self::INDEX_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function columnDoesNotExist($columnName)
|
||||
{
|
||||
return new self("An unknown column-name $columnName was given.", self::COLUMN_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function tableAlreadyExists($tableName)
|
||||
{
|
||||
return new self("The table with name '".$tableName."' already exists.", self::TABLE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $columnName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function columnAlreadyExists($tableName, $columnName)
|
||||
{
|
||||
return new self(
|
||||
"The column '".$columnName."' on table '".$tableName."' already exists.", self::COLUMN_ALREADY_EXISTS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function sequenceAlreadyExists($sequenceName)
|
||||
{
|
||||
return new self("The sequence '".$sequenceName."' already exists.", self::SEQUENCE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sequenceName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function sequenceDoesNotExist($sequenceName)
|
||||
{
|
||||
return new self("There exists no sequence with the name '".$sequenceName."'.", self::SEQUENCE_DOENST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fkName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function foreignKeyDoesNotExist($fkName)
|
||||
{
|
||||
return new self("There exists no foreign key with the name '".$fkName."'.", self::FOREIGNKEY_DOESNT_EXIST);
|
||||
}
|
||||
|
||||
static public function namedForeignKeyRequired($localTable, $foreignKey)
|
||||
{
|
||||
return new self(
|
||||
"The performed schema operation on ".$localTable->getName()." requires a named foreign key, ".
|
||||
"but the given foreign key from (".implode(", ", $foreignKey->getColumns()).") onto foreign table ".
|
||||
"'".$foreignKey->getForeignTableName()."' (".implode(", ", $foreignKey->getForeignColumns()).") is currently ".
|
||||
"unnamed."
|
||||
);
|
||||
}
|
||||
|
||||
static public function alterTableChangeNotSupported($changeName) {
|
||||
return new self ("Alter table change not supported, given '$changeName'");
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
|
||||
/**
|
||||
* Sequence Structure
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Sequence extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_allocationSize = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_initialValue = 1;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $allocationSize
|
||||
* @param int $initialValue
|
||||
*/
|
||||
public function __construct($name, $allocationSize=1, $initialValue=1)
|
||||
{
|
||||
$this->_setName($name);
|
||||
$this->_allocationSize = (is_numeric($allocationSize))?$allocationSize:1;
|
||||
$this->_initialValue = (is_numeric($initialValue))?$initialValue:1;
|
||||
}
|
||||
|
||||
public function getAllocationSize()
|
||||
{
|
||||
return $this->_allocationSize;
|
||||
}
|
||||
|
||||
public function getInitialValue()
|
||||
{
|
||||
return $this->_initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptSequence($this);
|
||||
}
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* SqliteSchemaManager
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @version $Revision$
|
||||
* @since 2.0
|
||||
*/
|
||||
class SqliteSchemaManager extends AbstractSchemaManager
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public function dropDatabase($database)
|
||||
{
|
||||
if (file_exists($database)) {
|
||||
unlink($database);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public function createDatabase($database)
|
||||
{
|
||||
$params = $this->_conn->getParams();
|
||||
$driver = $params['driver'];
|
||||
$options = array(
|
||||
'driver' => $driver,
|
||||
'path' => $database
|
||||
);
|
||||
$conn = \Doctrine\DBAL\DriverManager::getConnection($options);
|
||||
$conn->connect();
|
||||
$conn->close();
|
||||
}
|
||||
|
||||
protected function _getPortableTableDefinition($table)
|
||||
{
|
||||
return $table['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @license New BSD License
|
||||
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
|
||||
* @param array $tableIndexes
|
||||
* @param string $tableName
|
||||
* @return array
|
||||
*/
|
||||
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||
{
|
||||
$indexBuffer = array();
|
||||
|
||||
// fetch primary
|
||||
$stmt = $this->_conn->executeQuery( "PRAGMA TABLE_INFO ('$tableName')" );
|
||||
$indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
foreach($indexArray AS $indexColumnRow) {
|
||||
if($indexColumnRow['pk'] == "1") {
|
||||
$indexBuffer[] = array(
|
||||
'key_name' => 'primary',
|
||||
'primary' => true,
|
||||
'non_unique' => false,
|
||||
'column_name' => $indexColumnRow['name']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch regular indexes
|
||||
foreach($tableIndexes AS $tableIndex) {
|
||||
$keyName = $tableIndex['name'];
|
||||
$idx = array();
|
||||
$idx['key_name'] = $keyName;
|
||||
$idx['primary'] = false;
|
||||
$idx['non_unique'] = $tableIndex['unique']?false:true;
|
||||
|
||||
$stmt = $this->_conn->executeQuery( "PRAGMA INDEX_INFO ( '{$keyName}' )" );
|
||||
$indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ( $indexArray as $indexColumnRow ) {
|
||||
$idx['column_name'] = $indexColumnRow['name'];
|
||||
$indexBuffer[] = $idx;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::_getPortableTableIndexesList($indexBuffer, $tableName);
|
||||
}
|
||||
|
||||
protected function _getPortableTableIndexDefinition($tableIndex)
|
||||
{
|
||||
return array(
|
||||
'name' => $tableIndex['name'],
|
||||
'unique' => (bool) $tableIndex['unique']
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||
{
|
||||
$e = explode('(', $tableColumn['type']);
|
||||
$tableColumn['type'] = $e[0];
|
||||
if (isset($e[1])) {
|
||||
$length = trim($e[1], ')');
|
||||
$tableColumn['length'] = $length;
|
||||
}
|
||||
|
||||
$dbType = strtolower($tableColumn['type']);
|
||||
|
||||
$length = isset($tableColumn['length']) ? $tableColumn['length'] : null;
|
||||
$unsigned = (boolean) isset($tableColumn['unsigned']) ? $tableColumn['unsigned'] : false;
|
||||
$fixed = false;
|
||||
$type = null;
|
||||
$default = $tableColumn['dflt_value'];
|
||||
if ($default == 'NULL') {
|
||||
$default = null;
|
||||
}
|
||||
$notnull = (bool) $tableColumn['notnull'];
|
||||
|
||||
if ( ! isset($tableColumn['name'])) {
|
||||
$tableColumn['name'] = '';
|
||||
}
|
||||
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
switch ($dbType) {
|
||||
case 'boolean':
|
||||
$type = 'boolean';
|
||||
break;
|
||||
case 'tinyint':
|
||||
$type = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type = 'smallint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'mediumint':
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'serial':
|
||||
$type = 'integer';
|
||||
$length = null;
|
||||
break;
|
||||
case 'bigint':
|
||||
case 'bigserial':
|
||||
$type = 'bigint';
|
||||
$length = null;
|
||||
break;
|
||||
case 'clob':
|
||||
$fixed = false;
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'varchar':
|
||||
case 'varchar2':
|
||||
case 'nvarchar':
|
||||
case 'ntext':
|
||||
case 'image':
|
||||
case 'nchar':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
$type = 'string';
|
||||
if ($length == '1') {
|
||||
$type = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($dbType, 'text')) {
|
||||
$type = 'clob';
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type = 'datetime';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
list($precision, $scale) = array_map('trim', explode(', ', $tableColumn['length']));
|
||||
$type = 'decimal';
|
||||
$length = null;
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$type = 'string';
|
||||
$length = null;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'length' => $length,
|
||||
'unsigned' => (bool) $unsigned,
|
||||
'fixed' => $fixed,
|
||||
'notnull' => $notnull,
|
||||
'default' => $default,
|
||||
'precision' => $precision,
|
||||
'scale' => $scale,
|
||||
'platformDetails' => array(
|
||||
'autoincrement' => (bool) $tableColumn['pk'],
|
||||
),
|
||||
);
|
||||
|
||||
return new Column($tableColumn['name'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||
}
|
||||
|
||||
protected function _getPortableViewDefinition($view)
|
||||
{
|
||||
return new View($view['name'], $view['sql']);
|
||||
}
|
||||
}
|
@ -1,662 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Schema\Visitor\Visitor;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
|
||||
/**
|
||||
* Object Representation of a table
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Table extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_NONE = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_SEQUENCE = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const ID_IDENTITY = 2;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_name = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_indexes = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_primaryKeyName = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_fkConstraints = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_idGeneratorType = self::ID_NONE;
|
||||
|
||||
/**
|
||||
* @var SchemaConfig
|
||||
*/
|
||||
protected $_schemaConfig = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $columns
|
||||
* @param array $indexes
|
||||
* @param array $fkConstraints
|
||||
* @param int $idGeneratorType
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType=self::ID_NONE, array $options=array())
|
||||
{
|
||||
if (strlen($tableName) == 0) {
|
||||
throw DBALException::invalidTableName($tableName);
|
||||
}
|
||||
|
||||
$this->_setName($tableName);
|
||||
$this->_idGeneratorType = $idGeneratorType;
|
||||
|
||||
foreach ($columns AS $column) {
|
||||
$this->_addColumn($column);
|
||||
}
|
||||
|
||||
foreach ($indexes AS $idx) {
|
||||
$this->_addIndex($idx);
|
||||
}
|
||||
|
||||
foreach ($fkConstraints AS $constraint) {
|
||||
$this->_addForeignKeyConstraint($constraint);
|
||||
}
|
||||
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SchemaConfig $schemaConfig
|
||||
*/
|
||||
public function setSchemaConfig(SchemaConfig $schemaConfig)
|
||||
{
|
||||
$this->_schemaConfig = $schemaConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
protected function _getMaxIdentifierLength()
|
||||
{
|
||||
if ($this->_schemaConfig instanceof SchemaConfig) {
|
||||
return $this->_schemaConfig->getMaxIdentifierLength();
|
||||
} else {
|
||||
return 63;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Primary Key
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function setPrimaryKey(array $columns, $indexName = false)
|
||||
{
|
||||
$primaryKey = $this->_createIndex($columns, $indexName ?: "primary", true, true);
|
||||
|
||||
foreach ($columns AS $columnName) {
|
||||
$column = $this->getColumn($columnName);
|
||||
$column->setNotnull(true);
|
||||
}
|
||||
|
||||
return $primaryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return Table
|
||||
*/
|
||||
public function setIdGeneratorType($type)
|
||||
{
|
||||
$this->_idGeneratorType = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function addIndex(array $columnNames, $indexName = null)
|
||||
{
|
||||
if($indexName == null) {
|
||||
$indexName = $this->_generateIdentifierName(
|
||||
array_merge(array($this->getName()), $columnNames), "idx", $this->_getMaxIdentifierLength()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->_createIndex($columnNames, $indexName, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @return Table
|
||||
*/
|
||||
public function addUniqueIndex(array $columnNames, $indexName = null)
|
||||
{
|
||||
if ($indexName == null) {
|
||||
$indexName = $this->_generateIdentifierName(
|
||||
array_merge(array($this->getName()), $columnNames), "uniq", $this->_getMaxIdentifierLength()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->_createIndex($columnNames, $indexName, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an index begins in the order of the given columns.
|
||||
*
|
||||
* @param array $columnsNames
|
||||
* @return bool
|
||||
*/
|
||||
public function columnsAreIndexed(array $columnsNames)
|
||||
{
|
||||
foreach ($this->getIndexes() AS $index) {
|
||||
$indexColumns = $index->getColumns();
|
||||
$areIndexed = true;
|
||||
for ($i = 0; $i < count($columnsNames); $i++) {
|
||||
if ($columnsNames[$i] != $indexColumns[$i]) {
|
||||
$areIndexed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($areIndexed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $indexName
|
||||
* @param bool $isUnique
|
||||
* @param bool $isPrimary
|
||||
* @return Table
|
||||
*/
|
||||
private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary)
|
||||
{
|
||||
if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) {
|
||||
throw SchemaException::indexNameInvalid($indexName);
|
||||
}
|
||||
|
||||
foreach ($columnNames AS $columnName => $indexColOptions) {
|
||||
if (is_numeric($columnName) && is_string($indexColOptions)) {
|
||||
$columnName = $indexColOptions;
|
||||
}
|
||||
|
||||
if ( ! $this->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
$this->_addIndex(new Index($indexName, $columnNames, $isUnique, $isPrimary));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
* @param string $columnType
|
||||
* @param array $options
|
||||
* @return Column
|
||||
*/
|
||||
public function addColumn($columnName, $typeName, array $options=array())
|
||||
{
|
||||
$column = new Column($columnName, Type::getType($typeName), $options);
|
||||
|
||||
$this->_addColumn($column);
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename Column
|
||||
*
|
||||
* @param string $oldColumnName
|
||||
* @param string $newColumnName
|
||||
* @return Table
|
||||
*/
|
||||
public function renameColumn($oldColumnName, $newColumnName)
|
||||
{
|
||||
$column = $this->getColumn($oldColumnName);
|
||||
$this->dropColumn($oldColumnName);
|
||||
|
||||
$column->_setName($newColumnName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Column Details
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function changeColumn($columnName, array $options)
|
||||
{
|
||||
$column = $this->getColumn($columnName);
|
||||
$column->setOptions($options);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop Column from Table
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return Table
|
||||
*/
|
||||
public function dropColumn($columnName)
|
||||
{
|
||||
$columnName = strtolower($columnName);
|
||||
$column = $this->getColumn($columnName);
|
||||
unset($this->_columns[$columnName]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a foreign key constraint
|
||||
*
|
||||
* Name is inferred from the local columns
|
||||
*
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
|
||||
{
|
||||
$name = $this->_generateIdentifierName(array_merge((array)$this->getName(), $localColumnNames), "fk", $this->_getMaxIdentifierLength());
|
||||
return $this->addNamedForeignKeyConstraint($name, $foreignTable, $localColumnNames, $foreignColumnNames, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign key constraint
|
||||
*
|
||||
* Name is to be generated by the database itsself.
|
||||
*
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
|
||||
{
|
||||
return $this->addNamedForeignKeyConstraint(null, $foreignTable, $localColumnNames, $foreignColumnNames, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign key constraint with a given name
|
||||
*
|
||||
* @param string $name
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
|
||||
{
|
||||
if ($foreignTable instanceof Table) {
|
||||
$foreignTableName = $foreignTable->getName();
|
||||
|
||||
foreach ($foreignColumnNames AS $columnName) {
|
||||
if ( ! $foreignTable->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$foreignTableName = $foreignTable;
|
||||
}
|
||||
|
||||
foreach ($localColumnNames AS $columnName) {
|
||||
if ( ! $this->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
}
|
||||
|
||||
$constraint = new ForeignKeyConstraint(
|
||||
$localColumnNames, $foreignTableName, $foreignColumnNames, $name, $options
|
||||
);
|
||||
$this->_addForeignKeyConstraint($constraint);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return Table
|
||||
*/
|
||||
public function addOption($name, $value)
|
||||
{
|
||||
$this->_options[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Column $column
|
||||
*/
|
||||
protected function _addColumn(Column $column)
|
||||
{
|
||||
$columnName = $column->getName();
|
||||
$columnName = strtolower($columnName);
|
||||
|
||||
if (isset($this->_columns[$columnName])) {
|
||||
throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
|
||||
}
|
||||
|
||||
$this->_columns[$columnName] = $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add index to table
|
||||
*
|
||||
* @param Index $index
|
||||
* @return Table
|
||||
*/
|
||||
protected function _addIndex(Index $index)
|
||||
{
|
||||
// check for duplicates
|
||||
$c = new Comparator();
|
||||
foreach ($this->_indexes AS $existingIndex) {
|
||||
if ($c->diffIndex($index, $existingIndex) == false) {
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
$indexName = $index->getName();
|
||||
$indexName = strtolower($indexName);
|
||||
|
||||
if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $index->isPrimary())) {
|
||||
throw SchemaException::indexAlreadyExists($indexName);
|
||||
}
|
||||
|
||||
if ($index->isPrimary()) {
|
||||
$this->_primaryKeyName = $indexName;
|
||||
}
|
||||
|
||||
$this->_indexes[$indexName] = $index;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ForeignKeyConstraint $constraint
|
||||
*/
|
||||
protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)
|
||||
{
|
||||
$constraint->setLocalTable($this);
|
||||
|
||||
if(strlen($constraint->getName())) {
|
||||
$name = $constraint->getName();
|
||||
} else {
|
||||
$name = $this->_generateIdentifierName(
|
||||
array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength()
|
||||
);
|
||||
}
|
||||
$name = strtolower($name);
|
||||
|
||||
$this->_fkConstraints[$name] = $constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does Table have a foreign key constraint with the given name?
|
||||
* *
|
||||
* @param string $constraintName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasForeignKey($constraintName)
|
||||
{
|
||||
$constraintName = strtolower($constraintName);
|
||||
return isset($this->_fkConstraints[$constraintName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $constraintName
|
||||
* @return ForeignKeyConstraint
|
||||
*/
|
||||
public function getForeignKey($constraintName)
|
||||
{
|
||||
$constraintName = strtolower($constraintName);
|
||||
if(!$this->hasForeignKey($constraintName)) {
|
||||
throw SchemaException::foreignKeyDoesNotExist($constraintName);
|
||||
}
|
||||
|
||||
return $this->_fkConstraints[$constraintName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isIdGeneratorIdentity()
|
||||
{
|
||||
return ($this->_idGeneratorType==self::ID_IDENTITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function isIdGeneratorSequence()
|
||||
{
|
||||
return ($this->_idGeneratorType==self::ID_SEQUENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Column[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
$columns = $this->_columns;
|
||||
|
||||
$pkCols = array();
|
||||
$fkCols = array();
|
||||
|
||||
if ($this->hasIndex($this->_primaryKeyName)) {
|
||||
$pkCols = $this->getPrimaryKey()->getColumns();
|
||||
}
|
||||
foreach ($this->getForeignKeys() AS $fk) {
|
||||
/* @var $fk ForeignKeyConstraint */
|
||||
$fkCols = array_merge($fkCols, $fk->getColumns());
|
||||
}
|
||||
$colNames = array_unique(array_merge($pkCols, $fkCols, array_keys($columns)));
|
||||
|
||||
uksort($columns, function($a, $b) use($colNames) {
|
||||
return (array_search($a, $colNames) >= array_search($b, $colNames));
|
||||
});
|
||||
return $columns;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does this table have a column with the given name?
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumn($columnName)
|
||||
{
|
||||
$columnName = strtolower($columnName);
|
||||
return isset($this->_columns[$columnName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a column instance
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return Column
|
||||
*/
|
||||
public function getColumn($columnName)
|
||||
{
|
||||
$columnName = strtolower($columnName);
|
||||
if (!$this->hasColumn($columnName)) {
|
||||
throw SchemaException::columnDoesNotExist($columnName);
|
||||
}
|
||||
|
||||
return $this->_columns[$columnName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Index
|
||||
*/
|
||||
public function getPrimaryKey()
|
||||
{
|
||||
return $this->getIndex($this->_primaryKeyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIndex($indexName)
|
||||
{
|
||||
$indexName = strtolower($indexName);
|
||||
return (isset($this->_indexes[$indexName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexName
|
||||
* @return Index
|
||||
*/
|
||||
public function getIndex($indexName)
|
||||
{
|
||||
$indexName = strtolower($indexName);
|
||||
if (!$this->hasIndex($indexName)) {
|
||||
throw SchemaException::indexDoesNotExist($indexName);
|
||||
}
|
||||
return $this->_indexes[$indexName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getIndexes()
|
||||
{
|
||||
return $this->_indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Constraints
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getForeignKeys()
|
||||
{
|
||||
return $this->_fkConstraints;
|
||||
}
|
||||
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->_options[$name]);
|
||||
}
|
||||
|
||||
public function getOption($name)
|
||||
{
|
||||
return $this->_options[$name];
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visitor $visitor
|
||||
*/
|
||||
public function visit(Visitor $visitor)
|
||||
{
|
||||
$visitor->acceptTable($this);
|
||||
|
||||
foreach ($this->getColumns() AS $column) {
|
||||
$visitor->acceptColumn($this, $column);
|
||||
}
|
||||
|
||||
foreach ($this->getIndexes() AS $index) {
|
||||
$visitor->acceptIndex($this, $index);
|
||||
}
|
||||
|
||||
foreach ($this->getForeignKeys() AS $constraint) {
|
||||
$visitor->acceptForeignKey($this, $constraint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone of a Table triggers a deep clone of all affected assets
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->_columns AS $k => $column) {
|
||||
$this->_columns[$k] = clone $column;
|
||||
}
|
||||
foreach ($this->_indexes AS $k => $index) {
|
||||
$this->_indexes[$k] = clone $index;
|
||||
}
|
||||
foreach ($this->_fkConstraints AS $k => $fk) {
|
||||
$this->_fkConstraints[$k] = clone $fk;
|
||||
$this->_fkConstraints[$k]->setLocalTable($this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Table Diff
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class TableDiff
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $name = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $newName = false;
|
||||
|
||||
/**
|
||||
* All added fields
|
||||
*
|
||||
* @var array(string=>Column)
|
||||
*/
|
||||
public $addedColumns;
|
||||
|
||||
/**
|
||||
* All changed fields
|
||||
*
|
||||
* @var array(string=>Column)
|
||||
*/
|
||||
public $changedColumns = array();
|
||||
|
||||
/**
|
||||
* All removed fields
|
||||
*
|
||||
* @var array(string=>bool)
|
||||
*/
|
||||
public $removedColumns = array();
|
||||
|
||||
/**
|
||||
* Columns that are only renamed from key to column instance name.
|
||||
*
|
||||
* @var array(string=>Column)
|
||||
*/
|
||||
public $renamedColumns = array();
|
||||
|
||||
/**
|
||||
* All added indexes
|
||||
*
|
||||
* @var array(string=>Index)
|
||||
*/
|
||||
public $addedIndexes = array();
|
||||
|
||||
/**
|
||||
* All changed indexes
|
||||
*
|
||||
* @var array(string=>Index)
|
||||
*/
|
||||
public $changedIndexes = array();
|
||||
|
||||
/**
|
||||
* All removed indexes
|
||||
*
|
||||
* @var array(string=>bool)
|
||||
*/
|
||||
public $removedIndexes = array();
|
||||
|
||||
/**
|
||||
* All added foreign key definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $addedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* All changed foreign keys
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $changedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* All removed foreign keys
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $removedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* Constructs an TableDiff object.
|
||||
*
|
||||
* @param array(string=>Column) $addedColumns
|
||||
* @param array(string=>Column) $changedColumns
|
||||
* @param array(string=>bool) $removedColumns
|
||||
* @param array(string=>Index) $addedIndexes
|
||||
* @param array(string=>Index) $changedIndexes
|
||||
* @param array(string=>bool) $removedIndexes
|
||||
*/
|
||||
public function __construct($tableName, $addedColumns = array(),
|
||||
$changedColumns = array(), $removedColumns = array(), $addedIndexes = array(),
|
||||
$changedIndexes = array(), $removedIndexes = array())
|
||||
{
|
||||
$this->name = $tableName;
|
||||
$this->addedColumns = $addedColumns;
|
||||
$this->changedColumns = $changedColumns;
|
||||
$this->removedColumns = $removedColumns;
|
||||
$this->addedIndexes = $addedIndexes;
|
||||
$this->changedIndexes = $changedIndexes;
|
||||
$this->removedIndexes = $removedIndexes;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?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\Schema;
|
||||
|
||||
/**
|
||||
* Representation of a Database View
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class View extends AbstractAsset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_sql;
|
||||
|
||||
public function __construct($name, $sql)
|
||||
{
|
||||
$this->_setName($name);
|
||||
$this->_sql = $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->_sql;
|
||||
}
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
<?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\Schema\Visitor;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform,
|
||||
Doctrine\DBAL\Schema\Table,
|
||||
Doctrine\DBAL\Schema\Schema,
|
||||
Doctrine\DBAL\Schema\Column,
|
||||
Doctrine\DBAL\Schema\ForeignKeyConstraint,
|
||||
Doctrine\DBAL\Schema\Constraint,
|
||||
Doctrine\DBAL\Schema\Sequence,
|
||||
Doctrine\DBAL\Schema\Index;
|
||||
|
||||
class CreateSchemaSqlCollector implements Visitor
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createTableQueries = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createSequenceQueries = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_createFkConstraintQueries = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $_platform = null;
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function __construct(AbstractPlatform $platform)
|
||||
{
|
||||
$this->_platform = $platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function acceptSchema(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DDL Statements to create the accepted table with all its dependencies.
|
||||
*
|
||||
* @param Table $table
|
||||
*/
|
||||
public function acceptTable(Table $table)
|
||||
{
|
||||
$this->_createTableQueries = array_merge($this->_createTableQueries,
|
||||
$this->_platform->getCreateTableSQL($table)
|
||||
);
|
||||
}
|
||||
|
||||
public function acceptColumn(Table $table, Column $column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $localTable
|
||||
* @param ForeignKeyConstraint $fkConstraint
|
||||
*/
|
||||
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
|
||||
{
|
||||
// Append the foreign key constraints SQL
|
||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
||||
$this->_createFkConstraintQueries = array_merge($this->_createFkConstraintQueries,
|
||||
(array) $this->_platform->getCreateForeignKeySQL($fkConstraint, $localTable->getName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Index $index
|
||||
*/
|
||||
public function acceptIndex(Table $table, Index $index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
public function acceptSequence(Sequence $sequence)
|
||||
{
|
||||
$this->_createSequenceQueries = array_merge(
|
||||
$this->_createSequenceQueries, (array)$this->_platform->getCreateSequenceSQL($sequence)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function resetQueries()
|
||||
{
|
||||
$this->_createTableQueries = array();
|
||||
$this->_createSequenceQueries = array();
|
||||
$this->_createFkConstraintQueries = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all queries collected so far.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueries()
|
||||
{
|
||||
return array_merge(
|
||||
$this->_createTableQueries,
|
||||
$this->_createSequenceQueries,
|
||||
$this->_createFkConstraintQueries
|
||||
);
|
||||
}
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
<?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\Schema\Visitor;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform,
|
||||
Doctrine\DBAL\Schema\Table,
|
||||
Doctrine\DBAL\Schema\Schema,
|
||||
Doctrine\DBAL\Schema\Column,
|
||||
Doctrine\DBAL\Schema\ForeignKeyConstraint,
|
||||
Doctrine\DBAL\Schema\Constraint,
|
||||
Doctrine\DBAL\Schema\Sequence,
|
||||
Doctrine\DBAL\Schema\Index;
|
||||
|
||||
/**
|
||||
* Gather SQL statements that allow to completly drop the current schema.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class DropSchemaSqlCollector implements Visitor
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_constraints = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_sequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_tables = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $_platform = null;
|
||||
|
||||
/**
|
||||
* @param AbstractPlatform $platform
|
||||
*/
|
||||
public function __construct(AbstractPlatform $platform)
|
||||
{
|
||||
$this->_platform = $platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function acceptSchema(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
*/
|
||||
public function acceptTable(Table $table)
|
||||
{
|
||||
$this->_tables[] = $this->_platform->getDropTableSQL($table->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Column $column
|
||||
*/
|
||||
public function acceptColumn(Table $table, Column $column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $localTable
|
||||
* @param ForeignKeyConstraint $fkConstraint
|
||||
*/
|
||||
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
|
||||
{
|
||||
if (strlen($fkConstraint->getName()) == 0) {
|
||||
throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint);
|
||||
}
|
||||
|
||||
$this->_constraints[] = $this->_platform->getDropForeignKeySQL($fkConstraint->getName(), $localTable->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table $table
|
||||
* @param Index $index
|
||||
*/
|
||||
public function acceptIndex(Table $table, Index $index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sequence $sequence
|
||||
*/
|
||||
public function acceptSequence(Sequence $sequence)
|
||||
{
|
||||
$this->_sequences[] = $this->_platform->getDropSequenceSQL($sequence->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function clearQueries()
|
||||
{
|
||||
$this->_constraints = $this->_sequences = $this->_tables = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getQueries()
|
||||
{
|
||||
return array_merge(
|
||||
$this->_constraints,
|
||||
$this->_sequences,
|
||||
$this->_tables
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user