Commit d919b50e authored by Benjamin Eberlei's avatar Benjamin Eberlei

DBAL-6 - Add support for BLOBs

parent 33395dcc
# Upgrade to 2.2
## Doctrine\DBAL\Connection#insert and Doctrine\DBAL\Connnection#update
Both methods now accept an optional last parameter $types with binding types of the values passed.
This can potentially break child classes that have overwritten one of these methods.
\ No newline at end of file
......@@ -50,39 +50,39 @@ 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;
/**
* Represents an array of ints to be expanded by Doctrine SQL parsing.
*
*
* @var int
*/
const PARAM_INT_ARRAY = 101;
/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*
*
* @var int
*/
const PARAM_STR_ARRAY = 102;
/**
* Offset by which PARAM_* constants are detected as arrays of the param type.
*
*
* @var int
*/
const ARRAY_PARAM_OFFSET = 100;
......@@ -103,7 +103,7 @@ class Connection implements DriverConnection
* @var Doctrine\Common\EventManager
*/
protected $_eventManager;
/**
* @var Doctrine\DBAL\Query\ExpressionBuilder
*/
......@@ -165,10 +165,10 @@ class Connection implements DriverConnection
* @var Doctrine\DBAL\Driver
*/
protected $_driver;
/**
* Flag that indicates whether the current transaction is marked for rollback only.
*
*
* @var boolean
*/
private $_isRollbackOnly = false;
......@@ -196,16 +196,16 @@ class Connection implements DriverConnection
if ( ! $config) {
$config = new Configuration();
}
if ( ! $eventManager) {
$eventManager = new EventManager();
}
$this->_config = $config;
$this->_eventManager = $eventManager;
$this->_expr = new Query\Expression\ExpressionBuilder($this);
if ( ! isset($params['platform'])) {
$this->_platform = $driver->getDatabasePlatform();
} else if ($params['platform'] instanceof Platforms\AbstractPlatform) {
......@@ -213,7 +213,7 @@ class Connection implements DriverConnection
} else {
throw DBALException::invalidPlatformSpecified();
}
$this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
}
......@@ -236,40 +236,40 @@ class Connection implements DriverConnection
{
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()
......@@ -316,7 +316,7 @@ class Connection implements DriverConnection
{
return $this->_platform;
}
/**
* Gets the ExpressionBuilder for the connection.
*
......@@ -326,7 +326,7 @@ class Connection implements DriverConnection
{
return $this->_expr;
}
/**
* Establishes the connection with the database.
*
......@@ -357,7 +357,7 @@ class Connection implements DriverConnection
/**
* 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
......@@ -383,7 +383,7 @@ class Connection implements DriverConnection
/**
* 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
......@@ -406,7 +406,7 @@ class Connection implements DriverConnection
/**
* Checks whether a transaction is currently active.
*
*
* @return boolean TRUE if a transaction is currently active, FALSE otherwise.
*/
public function isTransactionActive()
......@@ -444,7 +444,7 @@ class Connection implements DriverConnection
public function close()
{
unset($this->_conn);
$this->_isConnected = false;
}
......@@ -456,7 +456,7 @@ class Connection implements DriverConnection
public function setTransactionIsolation($level)
{
$this->_transactionIsolationLevel = $level;
return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
}
......@@ -475,9 +475,10 @@ class Connection implements DriverConnection
*
* @param string $table The name of the table to update.
* @param array $identifier The update criteria. An associative array containing column-value pairs.
* @param array $types Types of the merged $data and $identifier arrays in that order.
* @return integer The number of affected rows.
*/
public function update($tableName, array $data, array $identifier)
public function update($tableName, array $data, array $identifier, array $types = array())
{
$this->connect();
$set = array();
......@@ -491,7 +492,7 @@ class Connection implements DriverConnection
. ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
. ' = ?';
return $this->executeUpdate($sql, $params);
return $this->executeUpdate($sql, $params, $types);
}
/**
......@@ -499,16 +500,17 @@ class Connection implements DriverConnection
*
* @param string $table The name of the table to insert data into.
* @param array $data An associative array containing column-value pairs.
* @param array $types Types of the inserted data.
* @return integer The number of affected rows.
*/
public function insert($tableName, array $data)
public function insert($tableName, array $data, array $types = array())
{
$this->connect();
// column names are specified as array keys
$cols = array();
$placeholders = array();
foreach ($data as $columnName => $value) {
$cols[] = $columnName;
$placeholders[] = '?';
......@@ -518,7 +520,7 @@ class Connection implements DriverConnection
. ' (' . implode(', ', $cols) . ')'
. ' VALUES (' . implode(', ', $placeholders) . ')';
return $this->executeUpdate($query, array_values($data));
return $this->executeUpdate($query, array_values($data), $types);
}
/**
......@@ -598,7 +600,7 @@ class Connection implements DriverConnection
* @param string $query The SQL query to execute.
* @param array $params The parameters to bind to the query, if any.
* @param array $types The types the previous parameters are in.
* @param QueryCacheProfile $qcp
* @param QueryCacheProfile $qcp
* @return Doctrine\DBAL\Driver\Statement The executed statement.
* @internal PERF: Directly prepares a driver statement, not a wrapper.
*/
......@@ -617,7 +619,7 @@ class Connection implements DriverConnection
if ($params) {
list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
$stmt = $this->_conn->prepare($query);
if ($types) {
$this->_bindTypedValues($stmt, $params, $types);
......@@ -693,7 +695,7 @@ class Connection implements DriverConnection
/**
* Executes an SQL statement, returning a result set as a Statement object.
*
*
* @param string $statement
* @param integer $fetchType
* @return Doctrine\DBAL\Driver\Statement
......@@ -721,7 +723,7 @@ class Connection implements DriverConnection
/**
* 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.
......@@ -741,7 +743,7 @@ class Connection implements DriverConnection
if ($params) {
list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
$stmt = $this->_conn->prepare($query);
if ($types) {
$this->_bindTypedValues($stmt, $params, $types);
......@@ -763,7 +765,7 @@ class Connection implements DriverConnection
/**
* Execute an SQL statement and return the number of affected rows.
*
*
* @param string $statement
* @return integer The number of affected rows.
*/
......@@ -1038,7 +1040,7 @@ class Connection implements DriverConnection
/**
* 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()
......@@ -1051,7 +1053,7 @@ class Connection implements DriverConnection
/**
* Check whether the current transaction is marked for rollback only.
*
*
* @return boolean
* @throws ConnectionException If no transaction is active.
*/
......@@ -1066,7 +1068,7 @@ class Connection implements DriverConnection
/**
* 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.
......@@ -1079,7 +1081,7 @@ class Connection implements DriverConnection
/**
* 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.
......@@ -1092,7 +1094,7 @@ class Connection implements DriverConnection
/**
* 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).
......@@ -1154,8 +1156,8 @@ class Connection implements DriverConnection
/**
* Create a new instance of a SQL query builder.
*
* @return Query\QueryBuilder
*
* @return Query\QueryBuilder
*/
public function createQueryBuilder()
{
......
......@@ -30,13 +30,15 @@ use \PDO;
class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
{
/** Statement handle. */
protected $_dbh;
protected $_sth;
protected $_executeMode;
protected static $_PARAM = ':param';
protected static $fetchStyleMap = array(
PDO::FETCH_BOTH => OCI_BOTH,
PDO::FETCH_ASSOC => OCI_ASSOC,
PDO::FETCH_NUM => OCI_NUM
PDO::FETCH_NUM => OCI_NUM,
PDO::PARAM_LOB => OCI_B_BLOB,
);
protected $_paramMap = array();
......@@ -50,6 +52,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
{
list($statement, $paramMap) = self::convertPositionalToNamedPlaceholders($statement);
$this->_sth = oci_parse($dbh, $statement);
$this->_dbh = $dbh;
$this->_paramMap = $paramMap;
$this->_executeMode = $executeMode;
}
......@@ -72,7 +75,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
* @return string
*/
static public function convertPositionalToNamedPlaceholders($statement)
{
{
$count = 1;
$inLiteral = false; // a valid query never starts with quotes
$stmtLen = strlen($statement);
......@@ -108,8 +111,15 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
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);
if ($type == \PDO::PARAM_LOB) {
$lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
$lob->writeTemporary($variable, OCI_TEMP_BLOB);
return oci_bind_by_name($this->_sth, $column, $lob, -1, OCI_B_BLOB);
} else {
return oci_bind_by_name($this->_sth, $column, $variable);
}
}
/**
......@@ -122,7 +132,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
return oci_free_statement($this->_sth);
}
/**
/**
* {@inheritdoc}
*/
public function columnCount()
......@@ -141,7 +151,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
}
return $error;
}
/**
* {@inheritdoc}
*/
......@@ -181,7 +191,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
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);
}
......@@ -193,11 +203,11 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
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;
}
......@@ -216,5 +226,5 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
public function rowCount()
{
return oci_num_rows($this->_sth);
}
}
}
......@@ -174,6 +174,11 @@ abstract class AbstractPlatform
*/
abstract public function getClobTypeDeclarationSQL(array $field);
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
abstract public function getBlobTypeDeclarationSQL(array $field);
/**
* Gets the name of the platform.
*
......@@ -203,7 +208,7 @@ abstract class AbstractPlatform
/**
* Get the Doctrine type that is mapped for the given database column type.
*
*
* @param string $dbType
* @return string
*/
......@@ -212,7 +217,7 @@ abstract class AbstractPlatform
if ($this->doctrineTypeMapping === null) {
$this->initializeDoctrineTypeMappings();
}
$dbType = strtolower($dbType);
if (isset($this->doctrineTypeMapping[$dbType])) {
return $this->doctrineTypeMapping[$dbType];
......@@ -264,7 +269,7 @@ abstract class AbstractPlatform
/**
* Mark this type as to be commented in ALTER TABLE and CREATE TABLE statements.
*
*
* @param Type $doctrineType
* @return void
*/
......@@ -278,7 +283,7 @@ abstract class AbstractPlatform
/**
* Get the comment to append to a column comment that helps parsing this type in reverse engineering.
*
*
* @param Type $doctrineType
* @return string
*/
......@@ -289,7 +294,7 @@ abstract class AbstractPlatform
/**
* Return the comment of a passed column modified by potential doctrine type comment hints.
*
*
* @param Column $column
* @return string
*/
......@@ -493,7 +498,7 @@ abstract class AbstractPlatform
{
$posStr = '';
$trimChar = ($char != false) ? $char . ' FROM ' : '';
if ($pos == self::TRIM_LEADING) {
$posStr = 'LEADING '.$trimChar;
} else if($pos == self::TRIM_TRAILING) {
......@@ -849,7 +854,7 @@ abstract class AbstractPlatform
/**
* Get SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction.
*
* @param Table|string $table
* @param Table|string $table
* @return string
*/
public function getDropTemporaryTableSQL($table)
......@@ -877,7 +882,7 @@ abstract class AbstractPlatform
/**
* Get drop constraint sql
*
*
* @param \Doctrine\DBAL\Schema\Constraint $constraint
* @param string|Table $table
* @return string
......@@ -1009,13 +1014,13 @@ abstract class AbstractPlatform
protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
{
$columnListSql = $this->getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $name => $definition) {
$columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
}
}
if (isset($options['primary']) && ! empty($options['primary'])) {
$columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
}
......@@ -1044,7 +1049,7 @@ abstract class AbstractPlatform
return $sql;
}
public function getCreateTemporaryTableSnippetSQL()
{
return "CREATE TEMPORARY TABLE";
......@@ -1060,11 +1065,11 @@ abstract class AbstractPlatform
{
throw DBALException::notSupported(__METHOD__);
}
/**
* Gets the SQL statement to change a sequence on this platform.
*
* @param \Doctrine\DBAL\Schema\Sequence $sequence
*
* @param \Doctrine\DBAL\Schema\Sequence $sequence
* @return string
*/
public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
......@@ -1111,7 +1116,7 @@ abstract class AbstractPlatform
foreach ($constraint->getForeignColumns() AS $column) {
$foreignColumns[] = $column;
}
$referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')';
}
$query .= ' '.$columnList.$referencesClause;
......@@ -1137,7 +1142,7 @@ abstract class AbstractPlatform
if (count($columns) == 0) {
throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
}
if ($index->isPrimary()) {
return $this->getCreatePrimaryKeySQL($index, $table);
} else {
......@@ -1152,10 +1157,10 @@ abstract class AbstractPlatform
return $query;
}
/**
* Get SQL to create an unnamed primary key constraint.
*
*
* @param Index $index
* @param string|Table $table
* @return string
......@@ -1217,7 +1222,7 @@ abstract class AbstractPlatform
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{
$tableName = $diff->name;
$sql = array();
if ($this->supportsForeignKeyConstraints()) {
foreach ($diff->removedForeignKeys AS $foreignKey) {
......@@ -1237,7 +1242,7 @@ abstract class AbstractPlatform
return $sql;
}
protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
{
if ($diff->newName !== false) {
......@@ -1265,7 +1270,7 @@ abstract class AbstractPlatform
return $sql;
}
/**
* Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
*
......@@ -1380,20 +1385,20 @@ abstract class AbstractPlatform
return $name . ' ' . $columnDef;
}
/**
* Gets the SQL snippet that declares a floating point column of arbitrary precision.
*
* @param array $columnDef
* @return string
*/
public function getDecimalTypeDeclarationSQL(array $columnDef)
public function getDecimalTypeDeclarationSQL(array $columnDef)
{
$columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision']))
? 10 : $columnDef['precision'];
$columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale']))
? 0 : $columnDef['scale'];
return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')';
}
......@@ -1447,14 +1452,14 @@ abstract class AbstractPlatform
return implode(', ', $constraints);
}
/**
* Obtain DBMS specific SQL code portion needed to set a unique
* constraint declaration to be used in statements like CREATE TABLE.
*
* @param string $name name of the unique constraint
* @param Index $index index definition
* @return string DBMS specific SQL code portion needed
* @return string DBMS specific SQL code portion needed
* to set a constraint
*/
public function getUniqueConstraintDeclarationSQL($name, Index $index)
......@@ -1462,9 +1467,9 @@ abstract class AbstractPlatform
if (count($index->getColumns()) == 0) {
throw \InvalidArgumentException("Incomplete definition. 'columns' required.");
}
return 'CONSTRAINT ' . $name . ' UNIQUE ('
. $this->getIndexFieldDeclarationListSQL($index->getColumns())
. $this->getIndexFieldDeclarationListSQL($index->getColumns())
. ')';
}
......@@ -1489,7 +1494,7 @@ abstract class AbstractPlatform
}
return $type . 'INDEX ' . $name . ' ('
. $this->getIndexFieldDeclarationListSQL($index->getColumns())
. $this->getIndexFieldDeclarationListSQL($index->getColumns())
. ')';
}
......@@ -1753,7 +1758,7 @@ abstract class AbstractPlatform
/**
* Some platforms need the boolean values to be converted.
*
*
* The default conversion in this implementation converts to integers (false => 0, true => 1).
*
* @param mixed $item
......@@ -1880,16 +1885,16 @@ abstract class AbstractPlatform
/**
* Get the list of indexes for the current database.
*
*
* The current database parameter is optional but will always be passed
* when using the SchemaManager API and is the database the given table is in.
*
*
* Attention: Some platforms only support currentDatabase when they
* are connected with that database. Cross-database information schema
* requests may be impossible.
*
*
* @param string $table
* @param string $currentDatabase
* @param string $currentDatabase
*/
public function getListTableIndexesSQL($table, $currentDatabase = null)
{
......@@ -1937,10 +1942,10 @@ abstract class AbstractPlatform
}
/**
* Obtain DBMS specific SQL to be used to create datetime fields in
* Obtain DBMS specific SQL to be used to create datetime fields in
* statements like CREATE TABLE
*
* @param array $fieldDeclaration
* @param array $fieldDeclaration
* @return string
*/
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
......@@ -1950,19 +1955,19 @@ abstract class AbstractPlatform
/**
* Obtain DBMS specific SQL to be used to create datetime with timezone offset fields.
*
*
* @param array $fieldDeclaration
*/
public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
{
return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration);
}
/**
* Obtain DBMS specific SQL to be used to create date fields in statements
* like CREATE TABLE.
*
*
* @param array $fieldDeclaration
* @return string
*/
......@@ -2090,17 +2095,17 @@ abstract class AbstractPlatform
/**
* Does this platform supports onUpdate in foreign key constraints?
*
*
* @return bool
*/
public function supportsForeignKeyOnUpdate()
{
return ($this->supportsForeignKeyConstraints() && true);
}
/**
* Whether the platform supports database schemas.
*
*
* @return boolean
*/
public function supportsSchemas()
......@@ -2141,7 +2146,7 @@ abstract class AbstractPlatform
/**
* Does this platform support the propriortary synatx "COMMENT ON asset"
*
*
* @return bool
*/
public function supportsCommentOnStatement()
......@@ -2157,7 +2162,7 @@ abstract class AbstractPlatform
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored datetime value of this platform.
*
*
* @return string The format string.
*/
public function getDateTimeFormatString()
......@@ -2179,18 +2184,18 @@ abstract class AbstractPlatform
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored date value of this platform.
*
*
* @return string The format string.
*/
public function getDateFormatString()
{
return 'Y-m-d';
}
/**
* Gets the format string, as accepted by the date() function, that describes
* the format of a stored time value of this platform.
*
*
* @return string The format string.
*/
public function getTimeFormatString()
......@@ -2200,7 +2205,7 @@ abstract class AbstractPlatform
/**
* Modify limit query
*
*
* @param string $query
* @param int $limit
* @param int $offset
......@@ -2237,10 +2242,10 @@ abstract class AbstractPlatform
return $query;
}
/**
* Gets the character casing of a column in an SQL result set of this platform.
*
*
* @param string $column The column name for which to get the correct character casing.
* @return string The column name in the character casing used in SQL result sets.
*/
......@@ -2248,11 +2253,11 @@ abstract class AbstractPlatform
{
return $column;
}
/**
* Makes any fixes to a name of a schema element (table, sequence, ...) that are required
* by restrictions of the platform, like a maximum length.
*
*
* @param string $schemaName
* @return string
*/
......@@ -2263,7 +2268,7 @@ abstract class AbstractPlatform
/**
* Maximum length of any given databse identifier, like tables or column names.
*
*
* @return int
*/
public function getMaxIdentifierLength()
......@@ -2274,8 +2279,8 @@ abstract class AbstractPlatform
/**
* Get the insert sql for an empty insert statement
*
* @param string $tableName
* @param string $identifierColumnName
* @param string $tableName
* @param string $identifierColumnName
* @return string $sql
*/
public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName)
......@@ -2300,7 +2305,7 @@ abstract class AbstractPlatform
/**
* This is for test reasons, many vendors have special requirements for dummy statements.
*
*
* @return string
*/
public function getDummySelectSQL()
......@@ -2343,9 +2348,9 @@ abstract class AbstractPlatform
/**
* Return the keyword list instance of this platform.
*
*
* Throws exception if no keyword list is specified.
*
*
* @throws DBALException
* @return KeywordList
*/
......@@ -2358,10 +2363,10 @@ abstract class AbstractPlatform
}
return $keywords;
}
/**
* The class name of the reserved keywords list.
*
*
* @return string
*/
protected function getReservedKeywordsClass()
......
......@@ -25,6 +25,14 @@ use Doctrine\DBAL\Schema\TableDiff;
class DB2Platform extends AbstractPlatform
{
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
throw DBALException::notSupported(__METHOD__);
}
public function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
......@@ -347,7 +355,7 @@ class DB2Platform extends AbstractPlatform
$indexes = $options['indexes'];
}
$options['indexes'] = array();
$sqls = parent::_getCreateTableSQL($tableName, $columns, $options);
foreach ($indexes as $index => $definition) {
......@@ -550,7 +558,7 @@ class DB2Platform extends AbstractPlatform
{
return false;
}
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords';
......
......@@ -40,26 +40,26 @@ class MsSqlPlatform extends AbstractPlatform
/**
* {@inheritDoc}
*/
public function getDateDiffExpression($date1, $date2)
public function getDateDiffExpression($date1, $date2)
{
return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')';
}
public function getDateAddDaysExpression($date, $days)
{
return 'DATEADD(day, ' . $days . ', ' . $date . ')';
}
public function getDateSubDaysExpression($date, $days)
{
return 'DATEADD(day, -1 * ' . $days . ', ' . $date . ')';
}
public function getDateAddMonthExpression($date, $months)
{
return 'DATEADD(month, ' . $months . ', ' . $date . ')';
}
public function getDateSubMonthExpression($date, $months)
{
return 'DATEADD(month, -1 * ' . $months . ', ' . $date . ')';
......@@ -278,7 +278,7 @@ class MsSqlPlatform extends AbstractPlatform
{
$queryParts = array();
$sql = array();
if ($diff->newName !== false) {
$queryParts[] = 'RENAME TO ' . $diff->newName;
}
......@@ -822,9 +822,17 @@ class MsSqlPlatform extends AbstractPlatform
{
return "[" . str_replace("]", "][", $str) . "]";
}
public function getTruncateTableSQL($tableName, $cascade = false)
{
return 'TRUNCATE TABLE '.$tableName;
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'VARBINARY(MAX)';
}
}
......@@ -46,7 +46,7 @@ class MySqlPlatform extends AbstractPlatform
{
return '`';
}
/**
* Returns the regular expression operator.
*
......@@ -137,9 +137,9 @@ class MySqlPlatform extends AbstractPlatform
}
/**
* Two approaches to listing the table indexes. The information_schema is
* Two approaches to listing the table indexes. The information_schema is
* prefered, because it doesn't cause problems with SQL keywords such as "order" or "table".
*
*
* @param string $table
* @param string $currentDatabase
* @return string
......@@ -150,7 +150,7 @@ class MySqlPlatform extends AbstractPlatform
return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ".
"SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ".
"CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " .
"NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " .
"NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " .
"FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'";
} else {
return 'SHOW INDEX FROM ' . $table;
......@@ -228,7 +228,7 @@ class MySqlPlatform extends AbstractPlatform
return 'DATETIME';
}
}
/**
* @override
*/
......@@ -240,10 +240,10 @@ class MySqlPlatform extends AbstractPlatform
/**
* @override
*/
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
{
return 'TIME';
}
}
/**
* @override
......@@ -265,7 +265,7 @@ class MySqlPlatform extends AbstractPlatform
{
return 'COLLATE ' . $collation;
}
/**
* Whether the platform prefers identity columns for ID generation.
* MySql prefers "autoincrement" identity columns since sequences can only
......@@ -278,7 +278,7 @@ class MySqlPlatform extends AbstractPlatform
{
return true;
}
/**
* Whether the platform supports identity columns.
* MySql supports this through AUTO_INCREMENT columns.
......@@ -300,7 +300,7 @@ class MySqlPlatform extends AbstractPlatform
{
return 'SHOW DATABASES';
}
public function getListTablesSQL()
{
return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
......@@ -329,7 +329,7 @@ class MySqlPlatform extends AbstractPlatform
{
return 'CREATE DATABASE ' . $name;
}
/**
* drop an existing database
*
......@@ -341,7 +341,7 @@ class MySqlPlatform extends AbstractPlatform
{
return 'DROP DATABASE ' . $name;
}
/**
* create a new table
*
......@@ -431,7 +431,7 @@ class MySqlPlatform extends AbstractPlatform
// default to innodb
$optionStrings[] = 'ENGINE = InnoDB';
}
if ( ! empty($optionStrings)) {
$query.= ' '.implode(' ', $optionStrings);
}
......@@ -442,10 +442,10 @@ class MySqlPlatform extends AbstractPlatform
$sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
}
}
return $sql;
}
/**
* Gets the SQL to alter an existing table.
*
......@@ -496,7 +496,7 @@ class MySqlPlatform extends AbstractPlatform
);
return $sql;
}
/**
* Obtain DBMS specific SQL code portion needed to declare an integer type
* field to be used in statements like CREATE TABLE.
......@@ -551,7 +551,7 @@ class MySqlPlatform extends AbstractPlatform
return $unsigned . $autoinc;
}
/**
* Return the FOREIGN KEY query section dealing with non-standard options
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
......@@ -569,7 +569,7 @@ class MySqlPlatform extends AbstractPlatform
$query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
return $query;
}
/**
* Gets the SQL to drop an index of a table.
*
......@@ -578,7 +578,7 @@ class MySqlPlatform extends AbstractPlatform
* @override
*/
public function getDropIndexSQL($index, $table=null)
{
{
if($index instanceof Index) {
$indexName = $index->getQuotedName($this);
} else if(is_string($index)) {
......@@ -586,25 +586,25 @@ class MySqlPlatform extends AbstractPlatform
} else {
throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
}
if($table instanceof Table) {
$table = $table->getQuotedName($this);
} else if(!is_string($table)) {
throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
}
if ($index instanceof Index && $index->isPrimary()) {
// mysql primary keys are always named "PRIMARY",
// mysql primary keys are always named "PRIMARY",
// so we cannot use them in statements because of them being keyword.
return $this->getDropPrimaryKeySQL($table);
}
return 'DROP INDEX ' . $indexName . ' ON ' . $table;
}
/**
* @param Index $index
* @param Table $table
* @param Table $table
*/
protected function getDropPrimaryKeySQL($table)
{
......@@ -664,7 +664,7 @@ class MySqlPlatform extends AbstractPlatform
{
return 65535;
}
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords';
......@@ -690,4 +690,12 @@ class MySqlPlatform extends AbstractPlatform
return 'DROP TEMPORARY TABLE ' . $table;
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'LONGBLOB';
}
}
......@@ -102,14 +102,14 @@ class OraclePlatform extends AbstractPlatform
/**
* Get the number of days difference between two dates.
*
*
* Note: Since Oracle timestamp differences are calculated down to the microsecond we have to truncate
* them to the difference in days. This is obviously a restriction of the original functionality, but we
* need to make this a portable function.
*
*
* @param type $date1
* @param type $date2
* @return type
* @return type
*/
public function getDateDiffExpression($date1, $date2)
{
......@@ -135,7 +135,7 @@ class OraclePlatform extends AbstractPlatform
{
return "ADD_MONTHS(" . $date . ", -" . $months . ")";
}
/**
* Gets the SQL used to create a sequence that starts with a given value
* and increments by the given allocation size.
......@@ -151,13 +151,13 @@ class OraclePlatform extends AbstractPlatform
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' START WITH ' . $sequence->getInitialValue() .
' MINVALUE ' . $sequence->getInitialValue() .
' MINVALUE ' . $sequence->getInitialValue() .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
......@@ -171,7 +171,7 @@ class OraclePlatform extends AbstractPlatform
{
return 'SELECT ' . $sequenceName . '.nextval FROM DUAL';
}
/**
* {@inheritdoc}
*
......@@ -197,7 +197,7 @@ class OraclePlatform extends AbstractPlatform
return parent::_getTransactionIsolationLevelSQL($level);
}
}
/**
* @override
*/
......@@ -281,7 +281,7 @@ class OraclePlatform extends AbstractPlatform
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)')
: ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)');
}
/** @override */
public function getClobTypeDeclarationSQL(array $field)
{
......@@ -318,11 +318,11 @@ class OraclePlatform extends AbstractPlatform
}
if (isset($column['autoincrement']) && $column['autoincrement'] ||
(isset($column['autoinc']) && $column['autoinc'])) {
(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);
......@@ -341,7 +341,7 @@ class OraclePlatform extends AbstractPlatform
public function getListTableIndexesSQL($table, $currentDatabase = null)
{
$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, " .
......@@ -392,7 +392,7 @@ BEGIN
IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $table).'\';
END IF;
END;';
END;';
$sequenceName = $table . '_SEQ';
$sequence = new \Doctrine\DBAL\Schema\Sequence($sequenceName, $start);
......@@ -476,12 +476,12 @@ LEFT JOIN all_cons_columns r_cols
{
$table = strtoupper($table);
$ownerCondition = '';
if(null !== $database){
$database = strtoupper($database);
$ownerCondition = "AND c.owner = '".$database."'";
}
return "SELECT c.*, d.comments FROM all_tab_columns c ".
"INNER JOIN all_col_comments d ON d.OWNER = c.OWNER AND d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ".
"WHERE c.table_name = '" . $table . "' ".$ownerCondition." ORDER BY c.column_name";
......@@ -639,12 +639,12 @@ LEFT JOIN all_cons_columns r_cols
}
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.
*/
......@@ -652,12 +652,12 @@ LEFT JOIN all_cons_columns r_cols
{
return strtoupper($column);
}
public function getCreateTemporaryTableSnippetSQL()
{
return "CREATE GLOBAL TEMPORARY TABLE";
}
public function getDateTimeTzFormatString()
{
return 'Y-m-d H:i:sP';
......@@ -672,7 +672,7 @@ LEFT JOIN all_cons_columns r_cols
{
return '1900-01-01 H:i:s';
}
public function fixSchemaElementName($schemaElementName)
{
if (strlen($schemaElementName) > 30) {
......@@ -769,9 +769,17 @@ LEFT JOIN all_cons_columns r_cols
{
return '';
}
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords';
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'BLOB';
}
}
......@@ -116,7 +116,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return "(" . $date . "- interval '" . $months . " month')";
}
/**
* parses a literal boolean value and returns
* proper sql equivalent
......@@ -128,7 +128,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return $value;
}*/
/**
* Whether the platform supports sequences.
* Postgres has native support for sequences.
......@@ -139,17 +139,17 @@ class PostgreSqlPlatform extends AbstractPlatform
{
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.
......@@ -165,7 +165,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return true;
}
/**
* Whether the platform prefers sequences for ID generation.
*
......@@ -187,7 +187,7 @@ class PostgreSqlPlatform extends AbstractPlatform
c.relname, n.nspname AS schemaname
FROM
pg_class c, pg_namespace n
WHERE relkind = 'S' AND n.oid = c.relnamespace AND
WHERE relkind = 'S' AND n.oid = c.relnamespace AND
(n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')";
}
......@@ -304,7 +304,7 @@ class PostgreSqlPlatform extends AbstractPlatform
AND n.oid = c.relnamespace
ORDER BY a.attnum";
}
/**
* create a new database
*
......@@ -357,7 +357,7 @@ class PostgreSqlPlatform extends AbstractPlatform
}
return $query;
}
/**
* generates the sql for altering an existing table on postgresql
*
......@@ -391,7 +391,7 @@ class PostgreSqlPlatform extends AbstractPlatform
foreach ($diff->changedColumns AS $columnDiff) {
$oldColumnName = $columnDiff->oldColumnName;
$column = $columnDiff->column;
if ($columnDiff->hasChanged('type')) {
$type = $column->getType();
......@@ -437,7 +437,7 @@ class PostgreSqlPlatform extends AbstractPlatform
return array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
}
/**
* Gets the SQL to create a sequence on this platform.
*
......@@ -451,13 +451,13 @@ class PostgreSqlPlatform extends AbstractPlatform
' MINVALUE ' . $sequence->getInitialValue() .
' START ' . $sequence->getInitialValue();
}
public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
/**
* Drop existing sequence
* @param \Doctrine\DBAL\Schema\Sequence $sequence
......@@ -480,7 +480,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return $this->getDropConstraintSQL($foreignKey, $table);
}
/**
* Gets the SQL used to create a table.
*
......@@ -516,7 +516,7 @@ class PostgreSqlPlatform extends AbstractPlatform
return $sql;
}
/**
* Postgres wants boolean values converted to the strings 'true'/'false'.
*
......@@ -549,7 +549,7 @@ class PostgreSqlPlatform extends AbstractPlatform
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
. $this->_getTransactionIsolationLevelSQL($level);
}
/**
* @override
*/
......@@ -566,7 +566,7 @@ class PostgreSqlPlatform extends AbstractPlatform
if ( ! empty($field['autoincrement'])) {
return 'SERIAL';
}
return 'INT';
}
......@@ -604,7 +604,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return 'TIMESTAMP(0) WITH TIME ZONE';
}
/**
* @override
*/
......@@ -640,7 +640,7 @@ class PostgreSqlPlatform extends AbstractPlatform
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
/** @override */
public function getClobTypeDeclarationSQL(array $field)
{
......@@ -656,12 +656,12 @@ class PostgreSqlPlatform extends AbstractPlatform
{
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.
*/
......@@ -669,7 +669,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return strtolower($column);
}
public function getDateTimeTzFormatString()
{
return 'Y-m-d H:i:sO';
......@@ -678,8 +678,8 @@ class PostgreSqlPlatform extends AbstractPlatform
/**
* Get the insert sql for an empty insert statement
*
* @param string $tableName
* @param string $identifierColumnName
* @param string $tableName
* @param string $identifierColumnName
* @return string $sql
*/
public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
......@@ -745,9 +745,17 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return 65535;
}
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords';
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'BYTEA';
}
}
......@@ -169,70 +169,70 @@ class SqlitePlatform extends AbstractPlatform
return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level);
}
/**
* @override
/**
* @override
*/
public function prefersIdentityColumns()
{
return true;
}
/**
* @override
/**
* @override
*/
public function getBooleanTypeDeclarationSQL(array $field)
{
return 'BOOLEAN';
}
/**
* @override
/**
* @override
*/
public function getIntegerTypeDeclarationSQL(array $field)
{
return $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* @override
/**
* @override
*/
public function getBigIntTypeDeclarationSQL(array $field)
{
return $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* @override
/**
* @override
*/
public function getTinyIntTypeDeclarationSql(array $field)
{
return $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* @override
/**
* @override
*/
public function getSmallIntTypeDeclarationSQL(array $field)
{
return $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* @override
/**
* @override
*/
public function getMediumIntTypeDeclarationSql(array $field)
{
return $this->_getCommonIntegerTypeDeclarationSQL($field);
}
/**
* @override
/**
* @override
*/
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
{
return 'DATETIME';
}
/**
* @override
*/
......@@ -249,8 +249,8 @@ class SqlitePlatform extends AbstractPlatform
return 'TIME';
}
/**
* @override
/**
* @override
*/
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
{
......@@ -330,7 +330,7 @@ class SqlitePlatform extends AbstractPlatform
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
}
public function getClobTypeDeclarationSQL(array $field)
{
return 'CLOB';
......@@ -487,9 +487,17 @@ class SqlitePlatform extends AbstractPlatform
'numeric' => 'decimal',
);
}
protected function getReservedKeywordsClass()
{
return 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords';
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
return 'BLOB';
}
}
......@@ -34,6 +34,16 @@ class BlobType extends Type
return $platform->getBlobTypeDeclarationSQL($fieldDeclaration);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
$hex='';
for ($i=0; $i < strlen($value); $i++) {
$hex .= dechex(ord($value[$i]));
}
return $value;
}
/**
* Converts a value from its database representation to its PHP representation
* of this type.
......@@ -44,11 +54,16 @@ class BlobType extends Type
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return (is_resource($value)) ? stream_get_contents($value) : $value;
if (is_string($value)) {
$value = fopen('data://text/plain;base64,' . base64_encode($value), 'r');
} else if ( ! is_resource($value)) {
throw ConversionException::conversionFailed($value, self::BLOB);
}
return $value;
}
public function getName()
{
return Type::TEXT;
return Type::BLOB;
}
}
\ No newline at end of file
......@@ -46,6 +46,7 @@ abstract class Type
const SMALLINT = 'smallint';
const STRING = 'string';
const TEXT = 'text';
const BLOB = 'blob';
const FLOAT = 'float';
/** Map of already instantiated type objects. One instance per type (flyweight). */
......@@ -67,6 +68,7 @@ abstract class Type
self::TIME => 'Doctrine\DBAL\Types\TimeType',
self::DECIMAL => 'Doctrine\DBAL\Types\DecimalType',
self::FLOAT => 'Doctrine\DBAL\Types\FloatType',
self::BLOB => 'Doctrine\DBAL\Types\BlobType',
);
/* Prevent instantiation and force use of the factory method. */
......@@ -194,15 +196,15 @@ abstract class Type
/**
* Gets the (preferred) binding type for values of this type that
* can be used when binding parameters to prepared statements.
*
*
* This method should return one of the PDO::PARAM_* constants, that is, one of:
*
*
* PDO::PARAM_BOOL
* PDO::PARAM_NULL
* PDO::PARAM_INT
* PDO::PARAM_STR
* PDO::PARAM_LOB
*
*
* @return integer
*/
public function getBindingType()
......@@ -244,7 +246,7 @@ abstract class Type
/**
* Modifies the SQL expression (identifier, parameter) to convert to a database value.
*
*
* @param string $sqlExpr
* @param AbstractPlatform $platform
* @return string
......
<?php
namespace Doctrine\Tests\DBAL\Functional;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Connection;
use PDO;
require_once __DIR__ . '/../../TestInit.php';
/**
* @group DBAL-6
*/
class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
public function setUp()
{
parent::setUp();
try {
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$table = new \Doctrine\DBAL\Schema\Table("blob_table");
$table->addColumn('id', 'integer');
$table->addColumn('clobfield', 'text');
$table->addColumn('blobfield', 'blob');
$table->setPrimaryKey(array('id'));
$sm = $this->_conn->getSchemaManager();
$sm->createTable($table);
} catch(\Exception $e) {
}
$this->_conn->exec($this->_conn->getDatabasePlatform()->getTruncateTableSQL('blob_table'));
}
public function testInsert()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
);
$this->assertEquals(1, $ret);
}
public function testSelect()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
);
$this->assertBlobContains('test');
}
public function testUpdate()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
);
$this->_conn->update('blob_table',
array('blobfield' => 'test2'),
array('id' => 1),
array(\PDO::PARAM_LOB, \PDO::PARAM_INT)
);
$this->assertBlobContains('test2');
}
private function assertBlobContains($text)
{
$rows = $this->_conn->fetchAll('SELECT * FROM blob_table');
$this->assertEquals(1, count($rows));
$row = array_change_key_case($rows[0], CASE_LOWER);
$blobValue = Type::getType('blob')->convertToPHPValue($row['blobfield'], $this->_conn->getDatabasePlatform());
$this->assertInternalType('resource', $blobValue);
$this->assertEquals($text, stream_get_contents($blobValue));
}
}
\ No newline at end of file
......@@ -6,6 +6,14 @@ use Doctrine\DBAL\Platforms;
class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform
{
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
throw DBALException::notSupported(__METHOD__);
}
public function getBooleanTypeDeclarationSQL(array $columnDef) {}
public function getIntegerTypeDeclarationSQL(array $columnDef) {}
public function getBigIntTypeDeclarationSQL(array $columnDef) {}
......@@ -16,7 +24,7 @@ class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform
{
return "DUMMYVARCHAR()";
}
/** @override */
public function getClobTypeDeclarationSQL(array $field)
{
......
......@@ -8,7 +8,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
private $_platformMock;
private $_lastInsertId = 0;
private $_inserts = array();
public function __construct(array $params, $driver, $config = null, $eventManager = null)
{
$this->_platformMock = new DatabasePlatformMock();
......@@ -18,7 +18,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
// Override possible assignment of platform to database platform mock
$this->_platform = $this->_platformMock;
}
/**
* @override
*/
......@@ -26,15 +26,15 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
{
return $this->_platformMock;
}
/**
* @override
*/
public function insert($tableName, array $data)
public function insert($tableName, array $data, array $types = array())
{
$this->_inserts[$tableName][] = $data;
}
/**
* @override
*/
......@@ -50,7 +50,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
{
return $this->_fetchOneResult;
}
/**
* @override
*/
......@@ -61,29 +61,29 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
}
return $input;
}
/* Mock API */
public function setFetchOneResult($fetchOneResult)
{
$this->_fetchOneResult = $fetchOneResult;
}
public function setDatabasePlatform($platform)
{
$this->_platformMock = $platform;
}
public function setLastInsertId($id)
{
$this->_lastInsertId = $id;
}
public function getInserts()
{
return $this->_inserts;
}
public function reset()
{
$this->_inserts = array();
......
......@@ -57,7 +57,7 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
/** @override */
public function getVarcharTypeDeclarationSQL(array $field) {}
/** @override */
public function getClobTypeDeclarationSQL(array $field) {}
......@@ -86,6 +86,13 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
}
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
}
/**
* Gets the SQL Snippet used to declare a BLOB column type.
*/
public function getBlobTypeDeclarationSQL(array $field)
{
throw DBALException::notSupported(__METHOD__);
}
}
\ No newline at end of file
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