blob: ef9fb7c053401b48d5ed03d8b45b99bc82c8adb9 [file] [log] [blame]
<?php
/**
* File containing the ezcQueryExpressionMssql class.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Database
* @version 1.0
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
* The ezcQueryExpressionMssql class is used to create SQL expression for SQL Server.
*
* This class reimplements the methods that have a different syntax in SQL Server.
*
* @package Database
* @version //autogentag//
*/
class ezcQueryExpressionMssql extends ezcQueryExpression
{
/**
* Contains an interval map from generic intervals to MS SQL native intervals.
*
* @var array(string=>string)
*/
protected $intervalMap = array(
'SECOND' => 'second',
'MINUTE' => 'minute',
'HOUR' => 'Hour',
'DAY' => 'Day',
'MONTH' => 'Month',
'YEAR' => 'Year',
);
/**
* Returns the remainder of the division operation
* $expression1 / $expression2.
*
* @param string $expression1
* @param string $expression2
* @return string
*/
public function mod( $expression1, $expression2 )
{
$expression1 = $this->getIdentifier( $expression1 );
$expression2 = $this->getIdentifier( $expression2 );
return "{$expression1} % {$expression2}";
}
/**
* Returns the md5 sum of a field.
*
* There are two variants of implementation for this feature.
* Both not ideal though.
* First don't require additional setup of MS SQL Server
* and uses undocumented function master.dbo.fn_varbintohexstr()
* to convert result of Transact-SQL HashBytes() function to string.
*
* Second one requires the stored procedure
* from http://www.thecodeproject.com/database/xp_md5.asp to
* be installed and wrapped by the user defined function fn_md5.
*
* @param string $column
* @return string
*/
public function md5( $column )
{
$column = $this->getIdentifier( $column );
return "SUBSTRING( master.dbo.fn_varbintohexstr( HashBytes( 'MD5', {$column} ) ), 3, 32)";
// alternative
// return "dbo.fn_md5( {$column} )";
}
/**
* Returns the length of a text field.
*
* @param string $column
* @return string
*/
public function length( $column )
{
$column = $this->getIdentifier( $column );
return "LEN( {$column} )";
}
/**
* Returns the current system date and time in the database internal
* format.
*
* @return string
*/
public function now()
{
return "CONVERT( varchar( 19 ), GETDATE(), 120 )"; // 120 means that we use ODBC canonical
// format for date output i.e. yyyy-mm-dd hh:mi:ss(24h)
}
/**
* Returns part of a string.
*
* Note: Not SQL92, but common functionality.
*
* @param string $value the target $value the string or the string column.
* @param int $from extract from this characeter.
* @param int $len extract this amount of characters. If $len is not
* provided it's assumed to be the number of characters
* to get the whole remainder of the string.
* @return string sql that extracts part of a string.
*/
public function subString( $value, $from, $len = null )
{
$value = $this->getIdentifier( $value );
if ( $len === null )
{
return "SUBSTRING( {$value}, {$from}, LEN({$value})-({$from}-1) )";
}
else
{
$len = $this->getIdentifier( $len );
return "SUBSTRING( {$value}, {$from}, {$len} )";
}
}
/**
* Returns a series of strings concatinated
*
* concat() accepts an arbitrary number of parameters. Each parameter
* must contain an expression or an array with expressions.
*
* @param string|array(string) $... strings that will be concatinated.
*/
public function concat()
{
$args = func_get_args();
$cols = ezcQuerySelect::arrayFlatten( $args );
if ( count( $cols ) < 1 )
{
throw new ezcQueryVariableParameterException( 'concat', count( $args ), 1 );
}
$cols = $this->getIdentifiers( $cols );
return join( ' + ', $cols );
}
/**
* Returns the SQL to locate the position of the first occurrence of a substring
*
* @param string $substr
* @param string $value
* @return string
*/
public function position( $substr, $value )
{
$value = $this->getIdentifier( $value );
return "CHARINDEX( '{$substr}', {$value} )";
}
/**
* Returns the SQL to calculate the next highest integer value from the number.
*
* @param string $number
* @return string
*/
public function ceil( $number )
{
$number = $this->getIdentifier( $number );
return " CEILING( {$number} ) ";
}
/**
* Returns the SQL that converts a timestamp value to number of seconds since 1970-01-01 00:00:00-00.
*
* @param string $column
* @return string
*/
public function unixTimestamp( $column )
{
$column = $this->getIdentifier( $column );
return " DATEDIFF(s, '19700101', {$column} ) - ".date('Z')." ";
}
/**
* Returns the SQL that subtracts an interval from a timestamp value.
*
* @param string $column
* @param numeric $expr
* @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
* @return string
*/
public function dateSub( $column, $expr, $type )
{
$type = $this->intervalMap[$type];
$column = $this->getIdentifier( $column );
return " CONVERT( varchar( 19 ), DATEADD( {$type}, -{$expr}, {$column} ), 120 ) ";
}
/**
* Returns the SQL that adds an interval to a timestamp value.
*
* @param string $column
* @param numeric $expr
* @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
* @return string
*/
public function dateAdd( $column, $expr, $type )
{
$type = $this->intervalMap[$type];
$column = $this->getIdentifier( $column );
return " CONVERT( varchar( 19 ), DATEADD( {$type}, +{$expr}, {$column} ), 120 ) ";
}
/**
* Returns the SQL that extracts parts from a timestamp value from a column.
*
* @param string $column
* @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
* @return string
*/
public function dateExtract( $column, $type )
{
$type = $this->intervalMap[$type];
$column = $this->getIdentifier( $column );
return " DATEPART( {$type}, {$column} ) ";
}
}
?>