Author: Sergey Alexeev
Date: 2007-05-03 22:15:43 +0200 (Thu, 03 May 2007)
New Revision: 5029
Log:
- Added feature #9960 [Database] sql abstraction.
Based on contributions by Joel Arvidsson and Friedel Hill.
Modified:
trunk/Database/ChangeLog
trunk/Database/src/handlers/sqlite.php
trunk/Database/src/sqlabstraction/expression.php
trunk/Database/src/sqlabstraction/implementations/expression_mssql.php
trunk/Database/src/sqlabstraction/implementations/expression_oracle.php
trunk/Database/src/sqlabstraction/implementations/expression_pgsql.php
trunk/Database/src/sqlabstraction/implementations/expression_sqlite.php
trunk/Database/src/sqlabstraction/implementations/query_sqlite_function_implementations.php
trunk/Database/tests/sqlabstraction/expression_test.php
Modified: trunk/Database/ChangeLog
===================================================================
--- trunk/Database/ChangeLog 2007-05-03 19:19:57 UTC (rev 5028)
+++ trunk/Database/ChangeLog 2007-05-03 20:15:43 UTC (rev 5029)
@@ -11,7 +11,9 @@
- Fixed issue #10529: Tests for quoting of strings in query expressions.
- Added feature #8448: Select Distinct not supported
- Added feature #7772: SQL Server implementation for the Database package.
- Based on contributions by Friedel Hill.
+ Based on contributions by Joel Arvidsson and Friedel Hill.
+- Added feature #9960 [Database] sql abstraction.
+ Based on contributions by Joel Arvidsson and Friedel Hill.
1.2 - Monday 18 December 2006
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Modified: trunk/Database/src/handlers/sqlite.php
===================================================================
--- trunk/Database/src/handlers/sqlite.php 2007-05-03 19:19:57 UTC (rev
5028)
+++ trunk/Database/src/handlers/sqlite.php 2007-05-03 20:15:43 UTC (rev
5029)
@@ -68,6 +68,9 @@
/* Register PHP implementations of missing functions in SQLite */
$this->sqliteCreateFunction( 'md5', array( 'ezcQuerySqliteFunctions',
'md5Impl'), 1 );
$this->sqliteCreateFunction( 'mod', array( 'ezcQuerySqliteFunctions',
'modImpl'), 2 );
+ $this->sqliteCreateFunction( 'locate', array(
'ezcQuerySqliteFunctions', 'positionImpl'), 2 );
+ $this->sqliteCreateFunction( 'floor', array(
'ezcQuerySqliteFunctions', 'floorImpl'), 1 );
+ $this->sqliteCreateFunction( 'ceil', array( 'ezcQuerySqliteFunctions',
'ceilImpl'), 1 );
$this->sqliteCreateFunction( 'concat', array(
'ezcQuerySqliteFunctions', 'concatImpl') );
$this->sqliteCreateFunction( 'now', 'time', 0 );
}
Modified: trunk/Database/src/sqlabstraction/expression.php
===================================================================
--- trunk/Database/src/sqlabstraction/expression.php 2007-05-03 19:19:57 UTC
(rev 5028)
+++ trunk/Database/src/sqlabstraction/expression.php 2007-05-03 20:15:43 UTC
(rev 5029)
@@ -47,6 +47,20 @@
private $quoteValues = true;
/**
+ * Contains an interval map from generic intervals to MySQL native
intervals.
+ *
+ * @var array(string=>string)
+ */
+ protected $intervalMap = array(
+ 'SECOND' => 'SECOND',
+ 'MINUTE' => 'MINUTE',
+ 'HOUR' => 'HOUR',
+ 'DAY' => 'DAY',
+ 'MONTH' => 'MONTH',
+ 'YEAR' => 'YEAR',
+ );
+
+ /**
* Constructs an empty ezcQueryExpression
* @param PDO $db
* @param array(string=>string) $aliases
@@ -809,5 +823,218 @@
$cols = $this->getIdentifiers( $cols );
return "CONCAT( " . 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 "LOCATE( '{$substr}', {$value} )";
+ }
+
+ /**
+ * Returns the SQL to change all characters to lowercase
+ *
+ * @param string $value
+ * @return string
+ */
+ public function lower( $value )
+ {
+ $value = $this->getIdentifier( $value );
+ return "LOWER( {$value} )";
+ }
+
+ /**
+ * Returns the SQL to change all characters to uppercase
+ *
+ * @param string $value
+ * @return string
+ */
+ public function upper( $value )
+ {
+ $value = $this->getIdentifier( $value );
+ return "UPPER( {$value} )";
+ }
+
+ /**
+ * Returns the SQL to calculate the next lowest integer value from the
number.
+ *
+ * @param string $number
+ * @return string
+ */
+ public function floor( $number )
+ {
+ $number = $this->getIdentifier( $number );
+ return " FLOOR( {$number} ) ";
+ }
+
+ /**
+ * 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 " CEIL( {$number} ) ";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise AND on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitAnd( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} & {$value2} )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise OR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitOr( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} | {$value2} )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise XOR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitXor( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} ^ {$value2} )";
+ }
+
+ /**
+ * Returns the SQL that converts a timestamp value to a unix timestamp.
+ *
+ * @param string $column
+ * @return string
+ */
+ public function unixTimestamp( $column )
+ {
+ $column = $this->getIdentifier( $column );
+ return " UNIX_TIMESTAMP( {$column} ) ";
+ }
+
+ /**
+ * 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 " {$column} - INTERVAL {$expr} {$type} ";
+ }
+
+ /**
+ * 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 " {$column} + INTERVAL {$expr} {$type} ";
+ }
+
+ /**
+ * Returns the SQL that extracts parts from a timestamp value.
+ *
+ * @param string $date
+ * @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 " EXTRACT( {$type} FROM {$column} ) ";
+ }
+
+ /**
+ * Returns a searched CASE statement.
+ *
+ * Accepts an arbitrary number of parameters.
+ * The first parameter (array) must always be specified, the last
+ * parameter (string) specifies the ELSE result.
+ *
+ * Example:
+ * <code>
+ * $q = ezcDbInstance::get()->createSelectQuery();
+ * $q->select(
+ * $q->expr->searchedCase(
+ * array( $q->expr->gte( 'column1', 20 ), 'column1' )
+ * , array( $q->expr->gte( 'column2', 50 ), 'column2' )
+ * , 'column3'
+ * )
+ * )
+ * ->from( 'table' );
+ * </code>
+ *
+ * @throws ezcQueryVariableParameterException
+ * @return string
+ */
+ public function searchedCase()
+ {
+ $args = func_get_args();
+ if ( count( $args ) === 0 )
+ {
+ throw new ezcQueryVariableParameterException( 'searchedCase',
count( $args ), 1 );
+ }
+
+ $expr = ' CASE';
+ foreach( $args as $arg )
+ {
+ if( is_array( $arg ) && count( $arg ) == 2 )
+ {
+ $column1 = $this->getIdentifier( $arg[0] );
+ $column2 = $this->getIdentifier( $arg[1] );
+ $expr .= " WHEN {$column1} THEN {$column2}";
+ }
+ else if( is_scalar( $arg ) )
+ {
+ $column = $this->getIdentifier( $arg );
+ $expr .= " ELSE {$column}";
+ }
+ }
+ $expr .= ' END ';
+
+ return $expr;
+ }
}
?>
Modified: trunk/Database/src/sqlabstraction/implementations/expression_mssql.php
===================================================================
--- trunk/Database/src/sqlabstraction/implementations/expression_mssql.php
2007-05-03 19:19:57 UTC (rev 5028)
+++ trunk/Database/src/sqlabstraction/implementations/expression_mssql.php
2007-05-03 20:15:43 UTC (rev 5029)
@@ -17,6 +17,19 @@
*/
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
@@ -35,7 +48,7 @@
/**
* Returns the md5 sum of a field.
- * There is two variants of implementation for this feature.
+ * 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()
@@ -43,7 +56,7 @@
*
* 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
+ * be installed and wrapped by the user defined function fn_md5.
*
* @return string
*/
@@ -124,5 +137,89 @@
$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.
+ *
+ * @param string $date
+ * @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} ) ";
+ }
}
?>
Modified:
trunk/Database/src/sqlabstraction/implementations/expression_oracle.php
===================================================================
--- trunk/Database/src/sqlabstraction/implementations/expression_oracle.php
2007-05-03 19:19:57 UTC (rev 5028)
+++ trunk/Database/src/sqlabstraction/implementations/expression_oracle.php
2007-05-03 20:15:43 UTC (rev 5029)
@@ -86,5 +86,153 @@
{
return "LOCALTIMESTAMP";
}
+
+ /**
+ * 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 "INSTR( {$value}, '{$substr}' )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise AND on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitAnd( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "bitand( {$value1}, {$value2} )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise OR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitOr( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} + {$value2} - bitand( {$value1}, {$value2} ) )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise XOR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitXor( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} + {$value2} - bitand( {$value1}, {$value2} ) * 2
)";
+ }
+
+ /**
+ * Returns the SQL that converts a timestamp value to a unix timestamp.
+ *
+ * @param string $column
+ * @return string
+ */
+ public function unixTimestamp( $column )
+ {
+ $column = $this->getIdentifier( $column );
+
+ if( $column != 'NOW()' )
+ {
+ $column = "CAST( {$column} AS TIMESTAMP )";
+// // alternative
+// if( preg_match( '/[0-9]{4}-[0-9]{2}-[0-9]{2}
[0-9]{2}:[0-9]{2}:[0-9]{2}/', $column ) ) {
+// $column = "TO_TIMESTAMP( {$column}, 'YYYY-MM-DD HH24:MI:SS'
)";
+// }
+ }
+
+ $date1 = "CAST( SYS_EXTRACT_UTC( {$column} ) AS DATE )";
+ $date2 = "TO_DATE( '19700101000000', 'YYYYMMDDHH24MISS' )";
+ return " ROUND( ( {$date1} - {$date2} ) / ( 1 / 86400 ) ) ";
+ }
+
+ /**
+ * 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 );
+
+ if( $column != 'NOW()' )
+ {
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ return " {$column} - INTERVAL '{$expr}' {$type} ";
+ }
+
+ /**
+ * 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 );
+
+ if( $column != 'NOW()' )
+ {
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ return " {$column} + INTERVAL '{$expr}' {$type} ";
+ }
+
+ /**
+ * Returns the SQL that extracts parts from a timestamp value.
+ *
+ * @param string $date
+ * @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 );
+
+ if( $column != 'NOW()' )
+ {
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ if( $type == 'SECOND' )
+ {
+ return " FLOOR( EXTRACT( {$type} FROM {$column} ) ) ";
+ }
+ else
+ {
+ return " EXTRACT( {$type} FROM {$column} ) ";
+ }
+ }
}
?>
Modified: trunk/Database/src/sqlabstraction/implementations/expression_pgsql.php
===================================================================
--- trunk/Database/src/sqlabstraction/implementations/expression_pgsql.php
2007-05-03 19:19:57 UTC (rev 5028)
+++ trunk/Database/src/sqlabstraction/implementations/expression_pgsql.php
2007-05-03 20:15:43 UTC (rev 5029)
@@ -124,5 +124,106 @@
{
return "LOCALTIMESTAMP(0)";
}
+
+ /**
+ * 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 "POSITION( '{$substr}' IN {$value} )";
+ }
+
+ /**
+ * Returns the SQL that performs the bitwise XOR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitXor( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( {$value1} # {$value2} )";
+ }
+
+ /**
+ * Returns the SQL that converts a timestamp value to a unix timestamp.
+ *
+ * @param string $column
+ * @return string
+ */
+ public function unixTimestamp( $column )
+ {
+ $column = $this->getIdentifier( $column );
+ return " EXTRACT( EPOCH FROM CAST( {$column} AS TIMESTAMP ) ) ";
+ }
+
+ /**
+ * 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];
+
+ if( $column != 'NOW()' )
+ {
+ $column = $this->getIdentifier( $column );
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ return " {$column} - INTERVAL '{$expr} {$type}' ";
+ }
+
+ /**
+ * 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];
+
+ if( $column != 'NOW()' )
+ {
+ $column = $this->getIdentifier( $column );
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ return " {$column} + INTERVAL '{$expr} {$type}' ";
+ }
+
+ /**
+ * Returns the SQL that extracts parts from a timestamp value.
+ *
+ * @param string $date
+ * @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
+ * @return string
+ */
+ public function dateExtract( $column, $type )
+ {
+ $type = $this->intervalMap[$type];
+
+ if( $column != 'NOW()' )
+ {
+ $column = $this->getIdentifier( $column );
+ $column = "CAST( {$column} AS TIMESTAMP )";
+ }
+
+ return " EXTRACT( {$type} FROM {$column} ) ";
+ }
}
?>
Modified:
trunk/Database/src/sqlabstraction/implementations/expression_sqlite.php
===================================================================
--- trunk/Database/src/sqlabstraction/implementations/expression_sqlite.php
2007-05-03 19:19:57 UTC (rev 5028)
+++ trunk/Database/src/sqlabstraction/implementations/expression_sqlite.php
2007-05-03 20:15:43 UTC (rev 5029)
@@ -21,6 +21,20 @@
class ezcQueryExpressionSqlite extends ezcQueryExpression
{
/**
+ * Contains an interval map from generic intervals to SQLite native
intervals.
+ *
+ * @var array(string=>string)
+ */
+ protected $intervalMap = array(
+ 'SECOND' => 'seconds',
+ 'MINUTE' => 'minutes',
+ 'HOUR' => 'hours',
+ 'DAY' => 'days',
+ 'MONTH' => 'months',
+ 'YEAR' => 'years',
+ );
+
+ /**
* Returns part of a string.
*
* Note: Not SQL92, but common functionality. SQLite only supports the 3
@@ -55,5 +69,110 @@
{
return '"' . date( 'Y-m-d H:i:s' ) . '"';
}
+
+ /**
+ * Returns the SQL that performs the bitwise XOR on two values.
+ *
+ * @param string $value1
+ * @param string $value2
+ * @return string
+ */
+ public function bitXor( $value1, $value2 )
+ {
+ $value1 = $this->getIdentifier( $value1 );
+ $value2 = $this->getIdentifier( $value2 );
+ return "( ( {$value1} | {$value2} ) - ( {$value1} & {$value2} ) )";
+ }
+
+ /**
+ * Returns the SQL that converts a timestamp value to a unix timestamp.
+ *
+ * @param string $column
+ * @return string
+ */
+ public function unixTimestamp( $column )
+ {
+ if( $column == 'NOW()' )
+ {
+ return " strftime( '%s', 'now' ) ";
+ }
+ else
+ {
+ $column = $this->getIdentifier( $column );
+ return " strftime( '%s', {$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 " datetime( {$column} , '-{$expr} {$type}' ) ";
+ }
+
+ /**
+ * 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 " datetime( {$column} , '+{$expr} {$type}' ) ";
+ }
+
+ /**
+ * Returns the SQL that extracts parts from a timestamp value.
+ *
+ * @param string $date
+ * @param string $type one of SECOND, MINUTE, HOUR, DAY, MONTH, or YEAR
+ * @return string
+ */
+ public function dateExtract( $column, $type )
+ {
+ switch ( $type )
+ {
+ case 'SECOND':
+ $type = '%S';
+ break;
+ case 'MINUTE':
+ $type = '%M';
+ break;
+ case 'HOUR':
+ $type = '%H';
+ break;
+ case 'DAY':
+ $type = '%d';
+ break;
+ case 'MONTH':
+ $type = '%m';
+ break;
+ case 'YEAR':
+ $type = '%Y';
+ break;
+ }
+
+ if( $column == 'NOW()' )
+ {
+ $column = "'now'";
+ }
+
+ $column = $this->getIdentifier( $column );
+ return " strftime( '{$type}', {$column} ) ";
+ }
}
?>
Modified:
trunk/Database/src/sqlabstraction/implementations/query_sqlite_function_implementations.php
===================================================================
---
trunk/Database/src/sqlabstraction/implementations/query_sqlite_function_implementations.php
2007-05-03 19:19:57 UTC (rev 5028)
+++
trunk/Database/src/sqlabstraction/implementations/query_sqlite_function_implementations.php
2007-05-03 20:15:43 UTC (rev 5029)
@@ -50,5 +50,39 @@
$args = func_get_args();
return join( '', $args );
}
+
+ /**
+ * Returns the SQL to locate the position of the first occurrence of a
substring
+ *
+ * @param string $substr
+ * @param string $value
+ * @return integer
+ */
+ static public function positionImpl( $substr, $value )
+ {
+ return strpos( $value, $substr ) + 1;
+ }
+
+ /**
+ * Returns the next lowest integer value from the number
+ *
+ * @param numeric $number
+ * @return integer
+ */
+ static public function floorImpl( $number )
+ {
+ return (int) floor( $number );
+ }
+
+ /**
+ * Returns the next highest integer value from the number
+ *
+ * @param numeric $number
+ * @return integer
+ */
+ static public function ceilImpl( $number )
+ {
+ return (int) ceil( $number );
+ }
}
?>
Modified: trunk/Database/tests/sqlabstraction/expression_test.php
===================================================================
--- trunk/Database/tests/sqlabstraction/expression_test.php 2007-05-03
19:19:57 UTC (rev 5028)
+++ trunk/Database/tests/sqlabstraction/expression_test.php 2007-05-03
20:15:43 UTC (rev 5029)
@@ -26,6 +26,7 @@
protected function setUp()
{
+
try {
$this->db = ezcDbInstance::get();
}
@@ -45,11 +46,24 @@
catch ( Exception $e ) {} // eat
// insert some data
- $this->db->exec( 'CREATE TABLE query_test ( id int, company
VARCHAR(255), section VARCHAR(255), employees int NULL)' );
- $this->db->exec( "INSERT INTO query_test VALUES ( 1, 'eZ systems',
'Norway', 20 )" );
- $this->db->exec( "INSERT INTO query_test VALUES ( 2, 'IBM', 'Norway',
500 )" );
- $this->db->exec( "INSERT INTO query_test VALUES ( 3, 'eZ systems',
'Ukraine', 10 )" );
- $this->db->exec( "INSERT INTO query_test VALUES ( 4, 'IBM', 'Germany',
null )" );
+ if ( $this->db->getName() === 'mssql' )
+ {
+ $this->db->exec( 'CREATE TABLE query_test ( id int, company
VARCHAR(255), section VARCHAR(255), employees int NULL, somedate DATETIME NULL
)' );
+ }
+ else
+ {
+ $this->db->exec( 'CREATE TABLE query_test ( id int, company
VARCHAR(255), section VARCHAR(255), employees int NULL, somedate TIMESTAMP )' );
+ }
+
+ if( $this->db->getName() === 'oracle' )
+ {
+ $this->db->exec( "ALTER SESSION SET NLS_TIMESTAMP_FORMAT =
'YYYY-MM-DD HH24:MI:SS'" ); // set the timestamp format
+ }
+
+ $this->db->exec( "INSERT INTO query_test VALUES ( 1, 'eZ systems',
'Norway', 20, '2007-05-03 11:54:17' )" );
+ $this->db->exec( "INSERT INTO query_test VALUES ( 2, 'IBM', 'Norway',
500, null )" );
+ $this->db->exec( "INSERT INTO query_test VALUES ( 3, 'eZ systems',
'Ukraine', 10, null )" );
+ $this->db->exec( "INSERT INTO query_test VALUES ( 4, 'IBM', 'Germany',
null, null )" );
}
protected function tearDown()
@@ -437,10 +451,31 @@
catch ( ezcQueryVariableParameterException $e ) {}
}
+ public function testSearchedCaseNone()
+ {
+ try
+ {
+ $this->e->searchedCase();
+ $this->fail( "Expected exception" );
+ }
+ catch ( ezcQueryVariableParameterException $e ) {}
+ }
+
+ public function testSearchedCase()
+ {
+ $reference = ' CASE WHEN 10 >= 20 THEN 1 WHEN 20 >= 20 THEN 2 ELSE 3
END ';
+ $result = $this->e->searchedCase(
+ array( $this->e->gte( 10, 20 ), 1 ),
+ array( $this->e->gte( 20, 20 ), 2 ),
+ 3
+ );
+ $this->assertSame( $reference, $result );
+ }
+
/**
- * Implementation tests, these are run on a selectQuery object so we know
- * we have the correct expression type.
- */
+ * Implementation tests, these are run on a selectQuery object so we know
+ * we have the correct expression type.
+ */
public function testlOrSingleImpl()
{
$this->q->select( '*' )->from( 'query_test' )
@@ -670,8 +705,8 @@
public function testInAlreadyQuotedImpl()
{
- $this->db->exec( "INSERT INTO query_test VALUES ( 5, 'ACME Inc.',
'''test-only''', null )" );
- $this->db->exec( "INSERT INTO query_test VALUES ( 6, 'ACME Inc.',
'\"test-only\"', null )" );
+ $this->db->exec( "INSERT INTO query_test VALUES ( 5, 'ACME Inc.',
'''test-only''', null, null )" );
+ $this->db->exec( "INSERT INTO query_test VALUES ( 6, 'ACME Inc.',
'\"test-only\"', null, null )" );
$this->q->select( '*' )->from( 'query_test' )
->where( $this->e->in( 'section', "'Norway'", "'Ukraine'",
"'test-only'", "\"test-only\"" ) );
@@ -889,7 +924,237 @@
$this->assertEquals( 'eZ systems rocks!', $stmt->fetchColumn( 0 ) );
}
- /**
+ public function testPositionImpl()
+ {
+ $this->q->select( $this->e->position( 's', "'eZ systems'" ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 4, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testLowerImpl()
+ {
+ $this->q->select( $this->e->lower( "'eZ systems'" ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 'ez systems', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testUpperImpl()
+ {
+ $this->q->select( $this->e->upper( "'eZ systems'" ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 'EZ SYSTEMS', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testFloorImpl()
+ {
+ $this->q->select( $this->e->floor( 3.33 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 3, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testCeilImpl()
+ {
+ $this->q->select( $this->e->ceil( 3.33 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 4, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testUnixTimestampImpl()
+ {
+ $this->q->select( $this->e->unixTimestamp( "'2007-05-03 11:54:17'" ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( strtotime( '2007-05-03 11:54:17' ),
(int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubSecondImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1,
'SECOND' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:54:16', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubMinuteImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1,
'MINUTE' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:53:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubHourImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1,
'HOUR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 10:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubDayImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1, 'DAY'
) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-02 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubMonthImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1,
'MONTH' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-04-03 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubYearImpl()
+ {
+ $this->q->select( $this->e->dateSub( "'2007-05-03 11:54:17'", 1,
'YEAR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2006-05-03 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddSecondImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1,
'SECOND' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:54:18', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddMinuteImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1,
'MINUTE' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:55:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddHourImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1,
'HOUR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 12:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddDayImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1, 'DAY'
) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-04 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddMonthImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1,
'MONTH' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-06-03 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddYearImpl()
+ {
+ $this->q->select( $this->e->dateAdd( "'2007-05-03 11:54:17'", 1,
'YEAR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2008-05-03 11:54:17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractSecondImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2007-05-03 11:54:17'",
'SECOND' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractMinuteImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2007-05-03 11:54:17'",
'MINUTE' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '54', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractHourImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2007-05-03 11:54:17'",
'HOUR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '11', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractDayImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2006-11-16 11:54:17'",
'DAY' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '16', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractMonthImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2006-11-16 11:54:17'",
'MONTH' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '11', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractYearImpl()
+ {
+ $this->q->select( $this->e->dateExtract( "'2006-11-16 11:54:17'",
'YEAR' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2006', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testSearchedCaseImpl()
+ {
+ $this->q->select(
+ $this->q->expr->searchedCase(
+ array( $this->e->gte( 10, 20 ), 1 ),
+ array( $this->e->gte( 20, 20 ), 2 ),
+ 3
+ )
+ );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 2, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testBitAndImpl()
+ {
+ $this->q->select( $this->e->bitAnd( 3, 10 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 2, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testBitOrImpl()
+ {
+ $this->q->select( $this->e->bitOr( 3, 10 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 11, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testBitXorImpl()
+ {
+ $this->q->select( $this->e->bitXor( 3, 10 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 9, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ /**
* Repeat of the implementation tests, but now testing with alias
functionality.
*/
// Not tested since it requires boolean field
@@ -1274,5 +1539,190 @@
$this->assertEquals( $reference, $this->q->getQuery() );
}
+ public function testPositionImplWithAlias()
+ {
+ $this->q->setAliases( array( 'text' => 'company' ) );
+ $this->q->select( $this->q->expr->position( 's', 'text' ) )
+ ->from( 'query_test' );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 4, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testLowerImplWithAlias()
+ {
+ $this->q->setAliases( array( 'text' => 'company' ) );
+ $this->q->select( $this->q->expr->lower( 'text' ) )
+ ->from( 'query_test' );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 'ez systems', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testUpperImplWithAlias()
+ {
+ $this->q->setAliases( array( 'text' => 'company' ) );
+ $this->q->select( $this->q->expr->upper( 'text' ) )
+ ->from( 'query_test' );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 'EZ SYSTEMS', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testFloorImplWithAlias()
+ {
+ $this->q->setAliases( array( 'empl' => 'employees' ) );
+ $this->q->select( $this->q->expr->floor( 'empl' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 20, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testCeilImplWithAlias()
+ {
+ $this->q->setAliases( array( 'empl' => 'employees' ) );
+ $this->q->select( $this->q->expr->ceil( 'empl' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 20, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testUnixTimestampImplWithAlias()
+ {
+ $this->q->setAliases( array( 'mydate' => 'somedate' ) );
+ $this->q->select( $this->q->expr->unixTimestamp( 'mydate' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( strtotime( '2007-05-03 11:54:17' ),
(int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateSubImplWithAlias()
+ {
+ $this->q->setAliases( array( 'mydate' => 'somedate' ) );
+ $this->q->select( $this->q->expr->dateSub( 'mydate', 1, 'SECOND' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:54:16', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateAddImplWithAlias()
+ {
+ $this->q->setAliases( array( 'mydate' => 'somedate' ) );
+ $this->q->select( $this->q->expr->dateAdd( 'mydate', 1, 'SECOND' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '2007-05-03 11:54:18', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testDateExtractImplWithAlias()
+ {
+ $this->q->setAliases( array( 'mydate' => 'somedate' ) );
+ $this->q->select( $this->q->expr->dateExtract( 'mydate', 'SECOND' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 1 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( '17', $stmt->fetchColumn( 0 ) );
+ }
+
+ public function testSearchedCaseImplWithAlias()
+ {
+ $this->q->setAliases( array( 'identifier' => 'id', 'empl' =>
'employees' ) );
+ $this->q->select(
+ $this->q->expr->searchedCase(
+ array( $this->q->expr->gte( 'empl', 20 ), 'empl' )
+ , 'identifier'
+ )
+ )
+ ->from( 'query_test' )
+ ->orderBy( 'query_test.id' );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $result = $stmt->fetchAll( PDO::FETCH_NUM );
+ $this->assertSame( 20, (int)$result[0][0] );
+ $this->assertSame( 500, (int)$result[1][0] );
+ $this->assertSame( 3, (int)$result[2][0] );
+ $this->assertSame( 4, (int)$result[3][0] );
+ }
+
+ public function testBitAndImplWithAlias()
+ {
+ $this->q->setAliases( array( 'empl' => 'employees' ) );
+ $this->q->select( $this->q->expr->bitAnd( 3, 'empl' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 3 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 2, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testBitOrImplWithAlias()
+ {
+ $this->q->setAliases( array( 'empl' => 'employees' ) );
+ $this->q->select( $this->q->expr->bitOr( 3, 'empl' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 3 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 11, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ public function testBitXorImplWithAlias()
+ {
+ $this->q->setAliases( array( 'empl' => 'employees' ) );
+ $this->q->select( $this->q->expr->bitXor( 3, 'empl' ) )
+ ->from( 'query_test' )
+ ->where( $this->q->expr->eq( 'id', 3 ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertSame( 9, (int)$stmt->fetchColumn( 0 ) );
+ }
+
+ /**
+ * Repeat of relevant implementation tests, but now testing with
ezcQueryExpression::now().
+ */
+ public function testUnixTimestampImplNow()
+ {
+ $this->q->select( $this->e->unixTimestamp( $this->q->expr->now() ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertEquals( time(), $stmt->fetchColumn( 0 ), '', 1 ); // with
delta 1
+ }
+
+ public function testDateSubImplNow()
+ {
+ $this->q->select( $this->e->dateSub( $this->q->expr->now(), 1,
'MINUTE' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertEquals( time() - 60, strtotime( $stmt->fetchColumn( 0 )
), '', 1 ); // with delta 1
+ }
+
+ public function testDateAddImplNow()
+ {
+ $this->q->select( $this->e->dateAdd( $this->q->expr->now(), 1,
'MINUTE' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $this->assertEquals( time() + 60, strtotime( $stmt->fetchColumn( 0 )
), '', 1 ); // with delta 1
+ }
+
+ public function testDateExtractImplNow()
+ {
+ $this->q->select( $this->e->dateExtract( $this->q->expr->now(),
'SECOND' ) );
+ $stmt = $this->q->prepare();
+ $stmt->execute();
+ $result = $stmt->fetchColumn( 0 );
+ $this->assertSame( (double)$result, floor( (double)$result ) );
+ $this->assertEquals( (int)date( 's' ), (int)$result, '', 1 ); // with
delta 1
+ }
}
?>
--
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components