Commit d0c9ef84 authored by Steve Müller's avatar Steve Müller

add SAP SQL Anywhere database vendor

parent 6ea864db
...@@ -4,9 +4,9 @@ Portability ...@@ -4,9 +4,9 @@ Portability
There are often cases when you need to write an application or library that is portable There are often cases when you need to write an application or library that is portable
across multiple different database vendors. The Doctrine ORM is one example of such across multiple different database vendors. The Doctrine ORM is one example of such
a library. It is an abstraction layer over all the currently supported vendors (MySQL, Oracle, a library. It is an abstraction layer over all the currently supported vendors (MySQL, Oracle,
PostgreSQL, SQLite and Microsoft SQL Server). If you want to use the DBAL to write a portable application PostgreSQL, SQLite, SAP SQL Anywhere and Microsoft SQL Server). If you want to use the DBAL
or library you have to follow lots of rules to make all the different vendors work the to write a portable application or library you have to follow lots of rules to make
same. all the different vendors work the same.
There are many different layers that you need to take care of, here is a quick list: There are many different layers that you need to take care of, here is a quick list:
...@@ -39,7 +39,7 @@ Connection Wrapper ...@@ -39,7 +39,7 @@ Connection Wrapper
This functionality is only implemented with Doctrine 2.1 upwards. This functionality is only implemented with Doctrine 2.1 upwards.
To handle all the points 1-3 you have to use a special wrapper around the database To handle all the points 1-3 you have to use a special wrapper around the database
connection. The handling and differences to tackle are all taken from the great connection. The handling and differences to tackle are all taken from the great
`PEAR MDB2 library <http://pear.php.net/package/MDB2/redirected>`_. `PEAR MDB2 library <http://pear.php.net/package/MDB2/redirected>`_.
Using the following code block in your initialization will: Using the following code block in your initialization will:
......
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
/**
* A Doctrine DBAL driver for the SAP Sybase SQL Anywhere PHP extension.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class Driver implements \Doctrine\DBAL\Driver
{
/**
* Build the connection string for given connection parameters and driver options.
*
* @param string $host Host address to connect to.
* @param integer $port Port to use for the connection (default to SQL Anywhere standard port 2683).
* @param string $server Database server name on the host to connect to.
* SQL Anywhere allows multiple database server instances on the same host,
* therefore specifying the server instance name to use is mandatory.
* @param string $dbname Name of the database on the server instance to connect to.
* @param string $username User name to use for connection authentication.
* @param string $password Password to use for connection authentication.
* @param array $driverOptions Additional parameters to use for the connection.
*
* @return string
*/
public function buildDsn($host, $port, $server, $dbname, $username = null, $password = null, array $driverOptions = array())
{
$port = $port ?: 2683;
return
'LINKS=tcpip(HOST=' . $host . ';PORT=' . $port . ';DoBroadcast=Direct)' .
';SERVER=' . $server .
';DBN=' . $dbname .
';UID=' . $username .
';PWD=' . $password .
';' . implode(
';',
array_map(function ($key, $value) {
return $key . '=' . $value;
}, array_keys($driverOptions), $driverOptions)
);
}
/**
* {@inheritdoc}
*
* @throws SQLAnywhereException
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
{
if ( ! isset($params['host'])) {
throw new SQLAnywhereException("Missing 'host' in configuration for sqlanywhere driver.");
}
if ( ! isset($params['server'])) {
throw new SQLAnywhereException("Missing 'server' in configuration for sqlanywhere driver.");
}
if ( ! isset($params['dbname'])) {
throw new SQLAnywhereException("Missing 'dbname' in configuration for sqlanywhere driver.");
}
return new SQLAnywhereConnection(
$this->buildDsn(
$params['host'],
isset($params['port']) ? $params['port'] : null,
$params['server'],
$params['dbname'],
$username,
$password,
$driverOptions
),
isset($params['persistent']) ? $params['persistent'] : false
);
}
/**
* {@inheritdoc}
*/
public function getDatabase(Connection $conn)
{
$params = $conn->getParams();
return $params['dbname'];
}
/**
* {@inheritdoc}
*/
public function getDatabasePlatform()
{
return new SQLAnywhere12Platform();
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'sqlanywhere';
}
/**
* {@inheritdoc}
*/
public function getSchemaManager(Connection $conn)
{
return new SQLAnywhereSchemaManager($conn);
}
}
\ No newline at end of file
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Connection;
/**
* SAP Sybase SQL Anywhere implementation of the Connection interface.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhereConnection implements Connection
{
/**
* @var resource The SQL Anywhere connection resource.
*/
private $conn;
/**
* Constructor.
*
* Connects to database with given connection string.
*
* @param string $dsn The connection string.
* @param boolean $persistent Whether or not to establish a persistent connection.
*
* @throws SQLAnywhereException
*/
public function __construct($dsn, $persistent = false)
{
$this->conn = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn);
if ( ! is_resource($this->conn) || get_resource_type($this->conn) != 'SQLAnywhere connection') {
throw SQLAnywhereException::fromSQLAnywhereError();
}
/**
* Disable PHP warnings on error
*/
if ( ! sasql_set_option($this->conn, 'verbose_errors', false)) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
/**
* Enable auto committing by default
*/
if ( ! sasql_set_option($this->conn, 'auto_commit', 'on')) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
/**
* Enable exact, non-approximated row count retrieval
*/
if ( ! sasql_set_option($this->conn, 'row_counts', true)) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
}
/**
* {@inheritdoc}
*
* @throws SQLAnywhereException
*/
public function beginTransaction()
{
if ( ! sasql_set_option($this->conn, 'auto_commit', 'off')) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
return true;
}
/**
* {@inheritdoc}
*
* @throws SQLAnywhereException
*/
public function commit()
{
if ( ! sasql_commit($this->conn)) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
$this->endTransaction();
return true;
}
/**
* {@inheritdoc}
*/
public function errorCode()
{
return sasql_errorcode($this->conn);
}
/**
* {@inheritdoc}
*/
public function errorInfo()
{
return sasql_error($this->conn);
}
/**
* {@inheritdoc}
*/
public function exec($statement)
{
$stmt = $this->prepare($statement);
$stmt->execute();
return $stmt->rowCount();
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
if ($name === null) {
return sasql_insert_id($this->conn);
}
return $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn();
}
/**
* {@inheritdoc}
*/
public function prepare($prepareString)
{
return new SQLAnywhereStatement($this->conn, $prepareString);
}
/**
* {@inheritdoc}
*/
public function query()
{
$args = func_get_args();
$stmt = $this->prepare($args[0]);
$stmt->execute();
return $stmt;
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = \PDO::PARAM_STR)
{
if (is_int($input) || is_float($input)) {
return $input;
}
return "'" . sasql_escape_string($this->conn, $input) . "'";
}
/**
* {@inheritdoc}
*
* @throws SQLAnywhereException
*/
public function rollBack()
{
if ( ! sasql_rollback($this->conn)) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
$this->endTransaction();
return true;
}
/**
* Ends transactional mode and enables auto commit again.
*
* @throws SQLAnywhereException
*
* @return boolean Whether or not ending transactional mode succeeded.
*/
private function endTransaction()
{
if ( ! sasql_set_option($this->conn, 'auto_commit', 'on')) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn);
}
return true;
}
}
\ No newline at end of file
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\DBALException;
/**
* SAP Sybase SQL Anywhere driver exception.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhereException extends DBALException
{
/**
* Helper method to turn SQL Anywhere error into exception.
*
* @param resource|null $conn The SQL Anywhere connection resource to retrieve the last error from.
* @param resource|null $stmt The SQL Anywhere statement resource to retrieve the last error from.
*
* @return SQLAnywhereException
*
* @throws \InvalidArgumentException
*/
public static function fromSQLAnywhereError($conn = null, $stmt = null)
{
if ($conn !== null && ! (is_resource($conn) && get_resource_type($conn) == 'SQLAnywhere connection')) {
throw new \InvalidArgumentException('Invalid SQL Anywhere connection resource given: ' . $conn);
}
if ($stmt !== null && ! (is_resource($stmt) && get_resource_type($stmt) == 'SQLAnywhere statement')) {
throw new \InvalidArgumentException('Invalid SQL Anywhere statement resource given: ' . $stmt);
}
$state = $conn ? sasql_sqlstate($conn) : sasql_sqlstate();
$code = null;
$message = null;
/**
* Try retrieving the last error from statement resource if given
*/
if ($stmt) {
$code = sasql_stmt_errno($stmt);
$message = sasql_stmt_error($stmt);
}
/**
* Try retrieving the last error from the connection resource
* if either the statement resource is not given or the statement
* resource is given but the last error could not be retrieved from it (fallback).
* Depending on the type of error, it is sometimes necessary to retrieve
* it from the connection resource even though it occurred during
* a prepared statement.
*/
if ($conn && ! $code) {
$code = sasql_errorcode($conn);
$message = sasql_error($conn);
}
/**
* Fallback mode if either no connection resource is given
* or the last error could not be retrieved from the given
* connection / statement resource.
*/
if ( ! $conn || ! $code) {
$code = sasql_errorcode();
$message = sasql_error();
}
if ($message) {
$message = 'SQLSTATE [' . $state . '] [' . $code . '] ' . $message;
} else {
$message = 'SQL Anywhere error occurred but no error message was retrieved from driver.';
}
return new self($message, $code);
}
}
This diff is collapsed.
...@@ -38,18 +38,19 @@ final class DriverManager ...@@ -38,18 +38,19 @@ final class DriverManager
* @var array * @var array
*/ */
private static $_driverMap = array( private static $_driverMap = array(
'pdo_mysql' => 'Doctrine\DBAL\Driver\PDOMySql\Driver', 'pdo_mysql' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver', 'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver',
'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver', 'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver', 'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver',
'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver', 'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver',
'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver', 'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver',
'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver', 'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver',
'pdo_sqlsrv' => 'Doctrine\DBAL\Driver\PDOSqlsrv\Driver', 'pdo_sqlsrv' => 'Doctrine\DBAL\Driver\PDOSqlsrv\Driver',
'mysqli' => 'Doctrine\DBAL\Driver\Mysqli\Driver', 'mysqli' => 'Doctrine\DBAL\Driver\Mysqli\Driver',
'drizzle_pdo_mysql' => 'Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver', 'drizzle_pdo_mysql' => 'Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver',
'sqlsrv' => 'Doctrine\DBAL\Driver\SQLSrv\Driver', 'sqlanywhere' => 'Doctrine\DBAL\Driver\SQLAnywhere\Driver',
); 'sqlsrv' => 'Doctrine\DBAL\Driver\SQLSrv\Driver'
);
/** /**
* Private constructor. This class cannot be instantiated. * Private constructor. This class cannot be instantiated.
...@@ -75,6 +76,7 @@ final class DriverManager ...@@ -75,6 +76,7 @@ final class DriverManager
* pdo_ibm (unstable) * pdo_ibm (unstable)
* pdo_sqlsrv * pdo_sqlsrv
* mysqli * mysqli
* sqlanywhere
* sqlsrv * sqlsrv
* ibm_db2 (unstable) * ibm_db2 (unstable)
* drizzle_pdo_mysql * drizzle_pdo_mysql
......
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms\Keywords;
/**
* SAP Sybase SQL Anywhere 11 reserved keywords list.
*
* @author Steve Müller <st.mueller@dzh-online.de>
*/
class SQLAnywhere11Keywords extends SQLAnywhereKeywords
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere11';
}
/**
* {@inheritdoc}
*
* @link http://dcx.sybase.com/1100/en/dbreference_en11/alhakeywords.html
*/
protected function getKeywords()
{
return array_merge(array_diff(parent::getKeywords(), array('IQ')), array(
'MERGE',
'OPENSTRING'
));
}
}
\ No newline at end of file
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms\Keywords;
/**
* SAP Sybase SQL Anywhere 12 reserved keywords list.
*
* @author Steve Müller <st.mueller@dzh-online.de>
*/
class SQLAnywhere12Keywords extends SQLAnywhere11Keywords
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere12';
}
/**
* {@inheritdoc}
*
* @link http://dcx.sybase.com/1200/en/dbreference/alhakeywords.html
*/
protected function getKeywords()
{
return array_merge(array_diff(parent::getKeywords(), array(
'INDEX_LPAREN',
'SYNTAX_ERROR',
'WITH_CUBE',
'WITH_LPAREN',
'WITH_ROLLUP'
)), array(
'DATETIMEOFFSET',
'LIMIT',
'OPENXML',
'SPATIAL',
'TREAT'
));
}
}
\ No newline at end of file
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms\Keywords;
/**
* SAP Sybase SQL Anywhere 10 reserved keywords list.
*
* @author Steve Müller <st.mueller@dzh-online.de>
*/
class SQLAnywhereKeywords extends KeywordList
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere';
}
/**
* {@inheritdoc}
*
* @link http://infocenter.sybase.com/help/topic/com.sybase.dbrfen10/pdf/dbrfen10.pdf?noframes=true
*/
protected function getKeywords()
{
return array(
'ADD',
'ALL',
'ALTER',
'AND',
'ANY',
'AS',
'ASC',
'ATTACH',
'BACKUP',
'BEGIN',
'BETWEEN',
'BIGINT',
'BINARY',
'BIT',
'BOTTOM',
'BREAK',
'BY',
'CALL',
'CAPABILITY',
'CASCADE',
'CASE',
'CAST',
'CHAR',
'CHAR_CONVERT',
'CHARACTER',
'CHECK',
'CHECKPOINT',
'CLOSE',
'COMMENT',
'COMMIT',
'COMPRESSED',
'CONFLICT',
'CONNECT',
'CONSTRAINT',
'CONTAINS',
'CONTINUE',
'CONVERT',
'CREATE',
'CROSS',
'CUBE',
'CURRENT',
'CURRENT_TIMESTAMP',
'CURRENT_USER',
'CURSOR',
'DATE',
'DBSPACE',
'DEALLOCATE',
'DEC',
'DECIMAL',
'DECLARE',
'DEFAULT',
'DELETE',
'DELETING',
'DESC',
'DETACH',
'DISTINCT',
'DO',
'DOUBLE',
'DROP',
'DYNAMIC',
'ELSE',
'ELSEIF',
'ENCRYPTED',
'END',
'ENDIF',
'ESCAPE',
'EXCEPT',
'EXCEPTION',
'EXEC',
'EXECUTE',
'EXISTING',
'EXISTS',
'EXTERNLOGIN',
'FETCH',
'FIRST',
'FLOAT',
'FOR',
'FORCE',
'FOREIGN',
'FORWARD',
'FROM',
'FULL',
'GOTO',
'GRANT',
'GROUP',
'HAVING',
'HOLDLOCK',
'IDENTIFIED',
'IF',
'IN',
'INDEX',
'INDEX_LPAREN',
'INNER',
'INOUT',
'INSENSITIVE',
'INSERT',
'INSERTING',
'INSTALL',
'INSTEAD',
'INT',
'INTEGER',
'INTEGRATED',
'INTERSECT',
'INTO',
'IQ',
'IS',
'ISOLATION',
'JOIN',
'KERBEROS',
'KEY',
'LATERAL',
'LEFT',
'LIKE',
'LOCK',
'LOGIN',
'LONG',
'MATCH',
'MEMBERSHIP',
'MESSAGE',
'MODE',
'MODIFY',
'NATURAL',
'NCHAR',
'NEW',
'NO',
'NOHOLDLOCK',
'NOT',
'NOTIFY',
'NULL',
'NUMERIC',
'NVARCHAR',
'OF',
'OFF',
'ON',
'OPEN',
'OPTION',
'OPTIONS',
'OR',
'ORDER',
'OTHERS',
'OUT',
'OUTER',
'OVER',
'PASSTHROUGH',
'PRECISION',
'PREPARE',
'PRIMARY',
'PRINT',
'PRIVILEGES',
'PROC',
'PROCEDURE',
'PUBLICATION',
'RAISERROR',
'READTEXT',
'REAL',
'REFERENCE',
'REFERENCES',
'REFRESH',
'RELEASE',
'REMOTE',
'REMOVE',
'RENAME',
'REORGANIZE',
'RESOURCE',
'RESTORE',
'RESTRICT',
'RETURN',
'REVOKE',
'RIGHT',
'ROLLBACK',
'ROLLUP',
'SAVE',
'SAVEPOINT',
'SCROLL',
'SELECT',
'SENSITIVE',
'SESSION',
'SET',
'SETUSER',
'SHARE',
'SMALLINT',
'SOME',
'SQLCODE',
'SQLSTATE',
'START',
'STOP',
'SUBTRANS',
'SUBTRANSACTION',
'SYNCHRONIZE',
'SYNTAX_ERROR',
'TABLE',
'TEMPORARY',
'THEN',
'TIME',
'TIMESTAMP',
'TINYINT',
'TO',
'TOP',
'TRAN',
'TRIGGER',
'TRUNCATE',
'TSEQUAL',
'UNBOUNDED',
'UNION',
'UNIQUE',
'UNIQUEIDENTIFIER',
'UNKNOWN',
'UNSIGNED',
'UPDATE',
'UPDATING',
'USER',
'USING',
'VALIDATE',
'VALUES',
'VARBINARY',
'VARBIT',
'VARCHAR',
'VARIABLE',
'VARYING',
'VIEW',
'WAIT',
'WAITFOR',
'WHEN',
'WHERE',
'WHILE',
'WINDOW',
'WITH',
'WITH_CUBE',
'WITH_LPAREN',
'WITH_ROLLUP',
'WITHIN',
'WORK',
'WRITETEXT',
'XML'
);
}
}
\ No newline at end of file
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms;
/**
* The SQLAnywhere11Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 11 database platform.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhere11Platform extends SQLAnywherePlatform
{
/**
* {@inheritdoc}
*/
public function getRegexpExpression()
{
return 'REGEXP';
}
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere11Keywords';
}
}
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
/**
* The SQLAnywhere12Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 12 database platform.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhere12Platform extends SQLAnywhere11Platform
{
/**
* {@inheritdoc}
*/
public function getCreateSequenceSQL(Sequence $sequence)
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
' START WITH ' . $sequence->getInitialValue() .
' MINVALUE ' . $sequence->getInitialValue();
}
/**
* {@inheritdoc}
*/
public function getAlterSequenceSQL(Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
/**
* {@inheritdoc}
*/
public function getDateTimeTzFormatString()
{
return 'Y-m-d H:i:s.uP';
}
/**
* {@inheritdoc}
*/
public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
{
return 'TIMESTAMP WITH TIME ZONE';
}
/**
* {@inheritdoc}
*/
public function getDropSequenceSQL($sequence)
{
if ($sequence instanceof Sequence) {
$sequence = $sequence->getQuotedName($this);
}
/** @var string $sequence */
return 'DROP SEQUENCE ' . $sequence;
}
/**
* {@inheritdoc}
*/
public function getListSequencesSQL($database)
{
return 'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE';
}
/**
* {@inheritdoc}
*/
public function getSequenceNextValSQL($sequenceName)
{
return 'SELECT ' . $sequenceName . '.NEXTVAL';
}
/**
* {@inheritdoc}
*/
public function supportsSequences()
{
return true;
}
/**
* {@inheritdoc}
*/
protected function getAdvancedIndexOptionsSQL(Index $index)
{
$sql = '';
if (!$index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_not_distinct')) {
$sql .= ' WITH NULLS NOT DISTINCT';
}
return $sql . parent::getAdvancedIndexOptionsSQL($index);
}
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere12Keywords';
}
/**
* {@inheritDoc}
*/
protected function initializeDoctrineTypeMappings()
{
parent::initializeDoctrineTypeMappings();
$this->doctrineTypeMapping['timestamp with time zone'] = 'datetime';
}
}
This diff is collapsed.
...@@ -42,6 +42,7 @@ class Connection extends \Doctrine\DBAL\Connection ...@@ -42,6 +42,7 @@ class Connection extends \Doctrine\DBAL\Connection
const PORTABILITY_SQLITE = 13; const PORTABILITY_SQLITE = 13;
const PORTABILITY_OTHERVENDORS = 12; const PORTABILITY_OTHERVENDORS = 12;
const PORTABILITY_DRIZZLE = 13; const PORTABILITY_DRIZZLE = 13;
const PORTABILITY_SQLANYWHERE = 13;
const PORTABILITY_SQLSRV = 13; const PORTABILITY_SQLSRV = 13;
/** /**
...@@ -71,6 +72,8 @@ class Connection extends \Doctrine\DBAL\Connection ...@@ -71,6 +72,8 @@ class Connection extends \Doctrine\DBAL\Connection
$params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE; $params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE;
} else if ($this->_platform->getName() === "drizzle") { } else if ($this->_platform->getName() === "drizzle") {
$params['portability'] = self::PORTABILITY_DRIZZLE; $params['portability'] = self::PORTABILITY_DRIZZLE;
} else if ($this->_platform->getName() === 'sqlanywhere') {
$params['portability'] = self::PORTABILITY_SQLANYWHERE;
} else if ($this->_platform->getName() === 'sqlsrv') { } else if ($this->_platform->getName() === 'sqlsrv') {
$params['portability'] = $params['portabililty'] & self::PORTABILITY_SQLSRV; $params['portability'] = $params['portabililty'] & self::PORTABILITY_SQLSRV;
} else { } else {
......
<?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 MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereException;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\View;
use Doctrine\DBAL\Types\Type;
/**
* SAP Sybase SQL Anywhere schema manager.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @link www.doctrine-project.org
* @since 2.5
*/
class SQLAnywhereSchemaManager extends AbstractSchemaManager
{
/**
* Holds instance of the database platform used for this schema manager
*
* @var \Doctrine\DBAL\Platforms\SQLAnywherePlatform $_platform
*/
protected $_platform;
/**
* {@inheritdoc}
*
* Starts a database after creation
* as SQL Anywhere needs a database to be started
* before it can be used.
*
* @see startDatabase
*/
public function createDatabase($database)
{
parent::createDatabase($database);
$this->startDatabase($database);
}
/**
* {@inheritdoc}
*
* Tries stopping a database before dropping
* as SQL Anywhere needs a database to be stopped
* before it can be dropped.
*
* @see stopDatabase
*/
public function dropDatabase($database)
{
$this->tryMethod('stopDatabase', $database);
parent::dropDatabase($database);
}
/**
* Starts a database.
*
* @param string $database The name of the database to start.
*/
public function startDatabase($database)
{
$this->_execSql($this->_platform->getStartDatabaseSQL($database));
}
/**
* Stops a database.
*
* @param string $database The name of the database to stop.
*/
public function stopDatabase($database)
{
$this->_execSql($this->_platform->getStopDatabaseSQL($database));
}
/**
* {@inheritdoc}
*/
protected function _getPortableDatabaseDefinition($database)
{
return $database['name'];
}
/**
* {@inheritdoc}
*/
protected function _getPortableSequenceDefinition($sequence)
{
return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['start_with']);
}
/**
* {@inheritdoc}
*/
protected function _getPortableTableColumnDefinition($tableColumn)
{
$type = $this->_platform->getDoctrineTypeMapping($tableColumn['type']);
$type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
$tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
$precision = null;
$scale = null;
$fixed = false;
$default = null;
if ($tableColumn['default']) {
/**
* Strip quotes from default value
*/
$default = preg_replace(array("/^'(.*)'$/", "/''/"), array("$1", "'"), $tableColumn['default']);
}
switch ($tableColumn['type']) {
case 'binary':
case 'char':
case 'nchar':
$fixed = true;
}
switch ($type) {
case 'decimal':
case 'float':
$precision = $tableColumn['length'];
$scale = $tableColumn['scale'];
}
return new Column(
$tableColumn['column_name'],
Type::getType($type),
array(
'length' => $type == 'string' ? $tableColumn['length'] : null,
'precision' => $precision,
'scale' => $scale,
'unsigned' => (bool) $tableColumn['unsigned'],
'fixed' => $fixed,
'notnull' => (bool) $tableColumn['notnull'],
'default' => $default,
'autoincrement' => (bool) $tableColumn['autoincrement'],
'comment' => $tableColumn['comment']
));
}
/**
* {@inheritdoc}
*/
protected function _getPortableTableDefinition($table)
{
return $table['table_name'];
}
/**
* {@inheritdoc}
*/
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
{
return new ForeignKeyConstraint(
$tableForeignKey['local_columns'],
$tableForeignKey['foreign_table'],
$tableForeignKey['foreign_columns'],
$tableForeignKey['name'],
$tableForeignKey['options']
);
}
/**
* {@inheritdoc}
*/
protected function _getPortableTableForeignKeysList($tableForeignKeys)
{
$foreignKeys = array();
foreach ($tableForeignKeys as $tableForeignKey) {
if (!isset($foreignKeys[$tableForeignKey['index_name']])) {
$foreignKeys[$tableForeignKey['index_name']] = array(
'local_columns' => array($tableForeignKey['local_column']),
'foreign_table' => $tableForeignKey['foreign_table'],
'foreign_columns' => array($tableForeignKey['foreign_column']),
'name' => $tableForeignKey['index_name'],
'options' => array(
'notnull' => $tableForeignKey['notnull'],
'match' => $tableForeignKey['match'],
'onUpdate' => $tableForeignKey['on_update'],
'onDelete' => $tableForeignKey['on_delete'],
'check_on_commit' => $tableForeignKey['check_on_commit'],
'clustered' => $tableForeignKey['clustered'],
'for_olap_workload' => $tableForeignKey['for_olap_workload']
)
);
} else {
$foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column'];
$foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column'];
}
}
return parent::_getPortableTableForeignKeysList($foreignKeys);
}
/**
* {@inheritdoc}
*/
protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null)
{
foreach ($tableIndexRows as &$tableIndex) {
$tableIndex['primary'] = (boolean) $tableIndex['primary'];
$tableIndex['flags'] = array();
if ($tableIndex['clustered']) {
$tableIndex['flags'][] = 'clustered';
}
if ($tableIndex['with_nulls_not_distinct']) {
$tableIndex['flags'][] = 'with_nulls_not_distinct';
}
if ($tableIndex['for_olap_workload']) {
$tableIndex['flags'][] = 'for_olap_workload';
}
}
return parent::_getPortableTableIndexesList($tableIndexRows, $tableName);
}
/**
* {@inheritdoc}
*/
protected function _getPortableViewDefinition($view)
{
return new View(
$view['table_name'],
preg_replace('/^.*\s+as\s+SELECT(.*)/i', "SELECT$1", $view['view_def'])
);
}
}
...@@ -41,6 +41,9 @@ class ReservedWordsCommand extends Command ...@@ -41,6 +41,9 @@ class ReservedWordsCommand extends Command
'pgsql' => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords', 'pgsql' => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords',
'oracle' => 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords', 'oracle' => 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords',
'db2' => 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords', 'db2' => 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords',
'sqlanywhere' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhereKeywords',
'sqlanywhere11' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere11Keywords',
'sqlanywhere12' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere12Keywords'
); );
/** /**
...@@ -73,8 +76,8 @@ class ReservedWordsCommand extends Command ...@@ -73,8 +76,8 @@ class ReservedWordsCommand extends Command
Checks if the current database contains tables and columns Checks if the current database contains tables and columns
with names that are identifiers in this dialect or in other SQL dialects. with names that are identifiers in this dialect or in other SQL dialects.
By default SQLite, MySQL, PostgreSQL, Microsoft SQL Server and Oracle By default SQLite, MySQL, PostgreSQL, Microsoft SQL Server, Oracle
keywords are checked: and SQL Anywhere keywords are checked:
<info>%command.full_name%</info> <info>%command.full_name%</info>
...@@ -93,6 +96,9 @@ The following keyword lists are currently shipped with Doctrine: ...@@ -93,6 +96,9 @@ The following keyword lists are currently shipped with Doctrine:
* sqlserver2005 * sqlserver2005
* sqlserver2008 * sqlserver2008
* sqlserver2012 * sqlserver2012
* sqlanywhere
* sqlanywhere11
* sqlanywhere12
* db2 (Not checked by default) * db2 (Not checked by default)
EOT EOT
); );
...@@ -116,7 +122,10 @@ EOT ...@@ -116,7 +122,10 @@ EOT
'sqlserver', 'sqlserver',
'sqlserver2005', 'sqlserver2005',
'sqlserver2008', 'sqlserver2008',
'sqlserver2012' 'sqlserver2012',
'sqlanywhere',
'sqlanywhere11',
'sqlanywhere12'
); );
} }
......
...@@ -4,18 +4,19 @@ ...@@ -4,18 +4,19 @@
# Just create the phpunit.xmls as described in the array below and configure the specific files <php /> section # Just create the phpunit.xmls as described in the array below and configure the specific files <php /> section
# to connect to that database. Just omit a file if you dont have that database and the tests will be skipped. # to connect to that database. Just omit a file if you dont have that database and the tests will be skipped.
configs[1]="mysql.phpunit.xml" configs[1]="mysql.phpunit.xml"
configs[2]='postgres.phpunit.xml' configs[2]='postgres.phpunit.xml'
configs[3]='sqlite.phpunit.xml' configs[3]='sqlite.phpunit.xml'
configs[4]='oracle.phpunit.xml' configs[4]='oracle.phpunit.xml'
configs[5]='db2.phpunit.xml' configs[5]='db2.phpunit.xml'
configs[6]='pdo-ibm.phpunit.xml' configs[6]='pdo-ibm.phpunit.xml'
configs[7]='sqlsrv.phpunit.xml' configs[7]='sqlsrv.phpunit.xml'
configs[8]='sqlanywhere.phpunit.xml'
for i in "${configs[@]}"; do for i in "${configs[@]}"; do
if [ -f "$i" ]; if [ -f "$i" ];
then then
echo "RUNNING TESTS WITH CONFIG $i" echo "RUNNING TESTS WITH CONFIG $i"
phpunit -c "$i" "$@" phpunit -c "$i" "$@"
fi; fi;
done done
<?php
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\View;
class SQLAnywhereSchemaManagerTest extends SchemaManagerFunctionalTestCase
{
public function testCreateAndListViews()
{
$this->createTestTable('view_test_table');
$name = "doctrine_test_view";
$sql = "SELECT * from DBA.view_test_table";
$view = new View($name, $sql);
$this->_sm->dropAndCreateView($view);
$views = $this->_sm->listViews();
$this->assertEquals(1, count($views), "Database has to have one view.");
$this->assertInstanceOf('Doctrine\DBAL\Schema\View', $views[$name]);
$this->assertEquals($name, $views[$name]->getName());
$this->assertEquals($sql, $views[$name]->getSql());
}
public function testDropAndCreateAdvancedIndex()
{
$table = $this->getTestTable('test_create_advanced_index');
$this->_sm->dropAndCreateTable($table);
$this->_sm->dropAndCreateIndex(
new Index('test', array('test'), true, false, array('clustered', 'with_nulls_not_distinct', 'for_olap_workload')),
$table->getName()
);
$tableIndexes = $this->_sm->listTableIndexes('test_create_advanced_index');
$this->assertInternalType('array', $tableIndexes);
$this->assertEquals('test', $tableIndexes['test']->getName());
$this->assertEquals(array('test'), $tableIndexes['test']->getColumns());
$this->assertTrue($tableIndexes['test']->isUnique());
$this->assertFalse($tableIndexes['test']->isPrimary());
$this->assertTrue($tableIndexes['test']->hasFlag('clustered'));
$this->assertTrue($tableIndexes['test']->hasFlag('with_nulls_not_distinct'));
$this->assertTrue($tableIndexes['test']->hasFlag('for_olap_workload'));
}
public function testListTableColumnsWithFixedStringTypeColumn()
{
$table = new Table('list_table_columns_char');
$table->addColumn('id', 'integer', array('notnull' => true));
$table->addColumn('test', 'string', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->dropAndCreateTable($table);
$columns = $this->_sm->listTableColumns('list_table_columns_char');
$this->assertArrayHasKey('test', $columns);
$this->assertTrue($columns['test']->getFixed());
}
}
<?php
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
class SQLAnywhere11PlatformTest extends SQLAnywherePlatformTest
{
/**
* @var \Doctrine\DBAL\Platforms\SQLAnywhere11Platform
*/
protected $_platform;
public function createPlatform()
{
return new SQLAnywhere11Platform;
}
public function testDoesNotSupportRegexp()
{
$this->markTestSkipped('This version of the platform now supports regular expressions.');
}
public function testGeneratesRegularExpressionSQLSnippet()
{
$this->assertEquals('REGEXP', $this->_platform->getRegexpExpression());
}
}
<?php
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
class SQLAnywhere12PlatformTest extends SQLAnywhere11PlatformTest
{
/**
* @var \Doctrine\DBAL\Platforms\SQLAnywhere12Platform
*/
protected $_platform;
public function createPlatform()
{
return new SQLAnywhere12Platform;
}
public function testDoesNotSupportSequences()
{
$this->markTestSkipped('This version of the platform now supports sequences.');
}
public function testSupportsSequences()
{
$this->assertTrue($this->_platform->supportsSequences());
}
public function testGeneratesSequenceSqlCommands()
{
$sequence = new Sequence('myseq', 20, 1);
$this->assertEquals(
'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
$this->_platform->getCreateSequenceSQL($sequence)
);
$this->assertEquals(
'ALTER SEQUENCE myseq INCREMENT BY 20',
$this->_platform->getAlterSequenceSQL($sequence)
);
$this->assertEquals(
'DROP SEQUENCE myseq',
$this->_platform->getDropSequenceSQL('myseq')
);
$this->assertEquals(
'DROP SEQUENCE myseq',
$this->_platform->getDropSequenceSQL($sequence)
);
$this->assertEquals(
"SELECT myseq.NEXTVAL",
$this->_platform->getSequenceNextValSQL('myseq')
);
$this->assertEquals(
'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
$this->_platform->getListSequencesSQL(null)
);
}
public function testGeneratesDateTimeTzColumnTypeDeclarationSQL()
{
$this->assertEquals(
'TIMESTAMP WITH TIME ZONE',
$this->_platform->getDateTimeTzTypeDeclarationSQL(array(
'length' => 10,
'fixed' => true,
'unsigned' => true,
'autoincrement' => true
))
);
}
public function testHasCorrectDateTimeTzFormatString()
{
$this->assertEquals('Y-m-d H:i:s.uP', $this->_platform->getDateTimeTzFormatString());
}
public function testInitializesDateTimeTzTypeMapping()
{
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
$this->assertEquals('datetime', $this->_platform->getDoctrineTypeMapping('timestamp with time zone'));
}
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL()
{
$this->assertEquals(
'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
$this->_platform->getCreateIndexSQL(
new Index(
'fooindex',
array('a', 'b'),
true,
false,
array('virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload')
),
'footable'
)
);
$this->assertEquals(
'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
$this->_platform->getCreateIndexSQL(
new Index(
'fooindex',
array('a', 'b'),
false,
false,
array('virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload')
),
'footable'
)
);
}
}
...@@ -17,6 +17,8 @@ class TestUtil ...@@ -17,6 +17,8 @@ class TestUtil
* 'db_username' : The username to use for connecting. * 'db_username' : The username to use for connecting.
* 'db_password' : The password to use for connecting. * 'db_password' : The password to use for connecting.
* 'db_host' : The hostname of the database to connect to. * 'db_host' : The hostname of the database to connect to.
* 'db_server' : The server name of the database to connect to
* (optional, some vendors allow multiple server instances with different names on the same host).
* 'db_name' : The name of the database to connect to. * 'db_name' : The name of the database to connect to.
* 'db_port' : The port of the database to connect to. * 'db_port' : The port of the database to connect to.
* *
...@@ -53,10 +55,18 @@ class TestUtil ...@@ -53,10 +55,18 @@ class TestUtil
'port' => $GLOBALS['tmpdb_port'] 'port' => $GLOBALS['tmpdb_port']
); );
if (isset($GLOBALS['db_server'])) {
$realDbParams['server'] = $GLOBALS['db_server'];
}
if (isset($GLOBALS['db_unix_socket'])) { if (isset($GLOBALS['db_unix_socket'])) {
$realDbParams['unix_socket'] = $GLOBALS['db_unix_socket']; $realDbParams['unix_socket'] = $GLOBALS['db_unix_socket'];
} }
if (isset($GLOBALS['tmpdb_server'])) {
$tmpDbParams['server'] = $GLOBALS['tmpdb_server'];
}
if (isset($GLOBALS['tmpdb_unix_socket'])) { if (isset($GLOBALS['tmpdb_unix_socket'])) {
$tmpDbParams['unix_socket'] = $GLOBALS['tmpdb_unix_socket']; $tmpDbParams['unix_socket'] = $GLOBALS['tmpdb_unix_socket'];
} }
...@@ -124,6 +134,10 @@ class TestUtil ...@@ -124,6 +134,10 @@ class TestUtil
'port' => $GLOBALS['tmpdb_port'] 'port' => $GLOBALS['tmpdb_port']
); );
if (isset($GLOBALS['tmpdb_server'])) {
$tmpDbParams['server'] = $GLOBALS['tmpdb_server'];
}
// Connect to tmpdb in order to drop and create the real test db. // Connect to tmpdb in order to drop and create the real test db.
return \Doctrine\DBAL\DriverManager::getConnection($tmpDbParams); return \Doctrine\DBAL\DriverManager::getConnection($tmpDbParams);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment