Commit cc7b1367 authored by zYne's avatar zYne

support for expressional column values

parent fa6523a4
......@@ -34,6 +34,33 @@ abstract class Doctrine_Adapter_Statement
public function bindValue($no, $value)
{
}
/**
* fetch
*
* @see Doctrine::FETCH_* constants
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Doctrine::FETCH_* constants,
* defaulting to Doctrine::FETCH_BOTH
*
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
* this value determines which row will be returned to the caller.
* This value must be one of the Doctrine::FETCH_ORI_* constants, defaulting to
* Doctrine::FETCH_ORI_NEXT. To request a scrollable cursor for your
* Doctrine_Adapter_Statement_Interface object,
* you must set the Doctrine::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
*
* @param integer $cursorOffset For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for which the
* $cursorOrientation parameter is set to Doctrine::FETCH_ORI_ABS, this value specifies
* the absolute number of the row in the result set that shall be fetched.
*
* For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for
* which the $cursorOrientation parameter is set to Doctrine::FETCH_ORI_REL, this value
* specifies the row to fetch relative to the cursor position before
* Doctrine_Adapter_Statement_Interface->fetch() was called.
*
* @return mixed
*/
public function fetch()
{
}
......@@ -55,6 +82,7 @@ abstract class Doctrine_Adapter_Statement
public function setFetchMode($mode)
{
}
public function columnCount(){
public function columnCount()
{
}
}
This diff is collapsed.
......@@ -474,10 +474,23 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
// build the statement
$query = 'INSERT INTO ' . $this->quoteIdentifier($table)
. '(' . implode(', ', $cols) . ') '
. 'VALUES (' . substr(str_repeat('?, ', count($values)), 0, -2) . ')';
. 'VALUES (';
$a = array();
foreach ($values as $k => $value) {
if ($value instanceof Doctrine_Expression) {
$value = $value->getSql();
unset($values[$k]);
} else {
$value = '?';
}
$a[] = $value;
}
$query .= implode(', ', $a) . ')';
// prepare and execute the statement
$this->execute($query, array_values($values));
$this->exec($query, array_values($values));
return true;
}
......
......@@ -139,7 +139,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/
public function saveGraph(Doctrine_Record $record)
{
$conn = $this->getConnection();
$conn = $this->getConnection();
if ($conn->transaction->isSaved($record)) {
return false;
......@@ -383,16 +383,22 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
if (empty($array)) {
return false;
}
$set = array();
$set = array();
foreach ($array as $name => $value) {
$set[] = $name . ' = ?';
if ($value instanceof Doctrine_Expression) {
$set[] = $value->getSql();
unset($array[$name]);
} else {
$set[] = $name . ' = ?';
if ($value instanceof Doctrine_Record) {
if ( ! $value->exists()) {
$record->save($this->conn);
if ($value instanceof Doctrine_Record) {
if ( ! $value->exists()) {
$record->save($this->conn);
}
$array[$name] = $value->getIncremented();
$record->set($name, $value->getIncremented());
}
$array[$name] = $value->getIncremented();
$record->set($name, $value->getIncremented());
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Firebird
*
......@@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Expression');
* @author Lorenzo Alberton <l.alberton@quipo.it> (PEAR MDB2 Interbase driver)
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
*/
class Doctrine_Expression_Firebird extends Doctrine_Expression
class Doctrine_Expression_Firebird extends Doctrine_Expression_Driver
{
/**
* return string for internal table used when calling only a function
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Connection_Module');
/**
* Doctrine_Expression_Mock
* Mock driver that is used for testing purposes
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Mock extends Doctrine_Expression_Driver
{ }
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Mssql
*
......@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Expression');
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Mssql extends Doctrine_Expression
class Doctrine_Expression_Mssql extends Doctrine_Expression_Driver
{
/**
* Return string to call a variable with the current timestamp inside an SQL statement
......@@ -59,10 +59,10 @@ class Doctrine_Expression_Mssql extends Doctrine_Expression
*/
public function substring($value, $position, $length = null)
{
if (!is_null($length)) {
return "SUBSTRING($value, $position, $length)";
if ( ! is_null($length)) {
return 'SUBSTRING(' . $value . ', ' . $position . ', ' . $length . ')';
}
return "SUBSTRING($value, $position, LEN($value) - $position + 1)";
return 'SUBSTRING(' . $value . ', ' . $position . ', LEN(' . $value . ') - ' . $position . ' + 1)';
}
/**
* Returns string to concatenate two or more string parameters
......
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Mysql
*
......@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Expression');
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Mysql extends Doctrine_Expression
class Doctrine_Expression_Mysql extends Doctrine_Expression_Driver
{
/**
* returns the regular expression operator
......
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Sqlite
*
......@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Expression');
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Oracle extends Doctrine_Expression
class Doctrine_Expression_Oracle extends Doctrine_Expression_Driver
{
/**
* Returns a series of strings concatinated
......
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Pgsql
*
......@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Expression');
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Pgsql extends Doctrine_Expression
class Doctrine_Expression_Pgsql extends Doctrine_Expression_Driver
{
/**
* Returns the md5 sum of a field.
......
......@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Expression');
Doctrine::autoload('Doctrine_Expression_Driver');
/**
* Doctrine_Expression_Sqlite
*
......@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Expression');
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Expression_Sqlite extends Doctrine_Expression
class Doctrine_Expression_Sqlite extends Doctrine_Expression_Driver
{
/**
* Returns the md5 sum of the data that SQLite's md5() function receives.
......
......@@ -631,7 +631,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_data = $stmt->fetch(PDO::FETCH_ASSOC);
if ( ! $this->_data) {
throw new Doctrine_Record_Exception('Failed to refresh. Record does not exist anymore');
throw new Doctrine_Record_Exception('Failed to refresh. Record does not exist.');
}
$this->_data = array_change_key_case($this->_data, CASE_LOWER);
......@@ -1049,7 +1049,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
default:
if ($this->_data[$v] instanceof Doctrine_Record) {
$this->_data[$v] = $this->_data[$v]->getIncremented();
}
}
$a[$v] = $this->_data[$v];
}
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Expression_Driver_TestCase
*
* @package Doctrine
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
*/
class Doctrine_Expression_Driver_TestCase extends Doctrine_UnitTestCase {
/**
* AGGREGATE FUNCTIONS
*/
public function testAvgReturnsValidSql() {
$this->expr = new Doctrine_Expression_Mock();
$this->assertEqual($this->expr->avg('id'), 'AVG(id)');
}
public function testCountReturnsValidSql() {
$this->assertEqual($this->expr->count('id'), 'COUNT(id)');
}
public function testMaxReturnsValidSql() {
$this->assertEqual($this->expr->max('id'), 'MAX(id)');
}
public function testMinReturnsValidSql() {
$this->assertEqual($this->expr->min('id'), 'MIN(id)');
}
public function testSumReturnsValidSql() {
$this->assertEqual($this->expr->sum('id'), 'SUM(id)');
}
public function testRegexpImplementedOnlyAtDriverLevel() {
try {
$this->expr->regexp('[abc]');
$this->fail();
} catch(Doctrine_Expression_Exception $e) {
$this->pass();
}
}
public function testSoundexImplementedOnlyAtDriverLevel() {
try {
$this->expr->soundex('arnold');
$this->fail();
} catch(Doctrine_Expression_Exception $e) {
$this->pass();
}
}
/**
* TIME FUNCTIONS
*/
public function testNowReturnsValidSql() {
$this->assertEqual($this->expr->now(), 'NOW()');
}
/**
* STRING FUNCTIONS
*/
public function testUpperReturnsValidSql() {
$this->assertEqual($this->expr->upper('id', 3), 'UPPER(id)');
}
public function testLowerReturnsValidSql() {
$this->assertEqual($this->expr->lower('id'), 'LOWER(id)');
}
public function testLengthReturnsValidSql() {
$this->assertEqual($this->expr->length('id'), 'LENGTH(id)');
}
public function testLtrimReturnsValidSql() {
$this->assertEqual($this->expr->ltrim('id'), 'LTRIM(id)');
}
public function testLocateReturnsValidSql() {
$this->assertEqual($this->expr->locate('id', 3), 'LOCATE(id, 3)');
}
public function testConcatReturnsValidSql() {
$this->assertEqual($this->expr->concat('id', 'type'), 'CONCAT(id, type)');
}
public function testSubstringReturnsValidSql() {
$this->assertEqual($this->expr->substring('id', 3), 'SUBSTRING(id FROM 3)');
$this->assertEqual($this->expr->substring('id', 3, 2), 'SUBSTRING(id FROM 3 FOR 2)');
}
/**
* MATH FUNCTIONS
*/
public function testRoundReturnsValidSql() {
$this->assertEqual($this->expr->round(2.3), 'ROUND(2.3, 0)');
$this->assertEqual($this->expr->round(2.3, 1), 'ROUND(2.3, 1)');
}
public function testModReturnsValidSql() {
$this->assertEqual($this->expr->mod(2, 3), 'MOD(2, 3)');
}
public function testSubReturnsValidSql() {
$this->assertEqual($this->expr->sub(array(2, 3)), '(2 - 3)');
}
public function testMulReturnsValidSql() {
$this->assertEqual($this->expr->mul(array(2, 3)), '(2 * 3)');
}
public function testAddReturnsValidSql() {
$this->assertEqual($this->expr->add(array(2, 3)), '(2 + 3)');
}
public function testDivReturnsValidSql() {
$this->assertEqual($this->expr->div(array(2, 3)), '(2 / 3)');
}
/**
* ASSERT OPERATORS
*/
public function testEqReturnsValidSql() {
$this->assertEqual($this->expr->eq(1, 1), '1 = 1');
}
public function testNeqReturnsValidSql() {
$this->assertEqual($this->expr->neq(1, 2), '1 <> 2');
}
public function testGtReturnsValidSql() {
$this->assertEqual($this->expr->gt(2, 1), '2 > 1');
}
public function testGteReturnsValidSql() {
$this->assertEqual($this->expr->gte(1, 1), '1 >= 1');
}
public function testLtReturnsValidSql() {
$this->assertEqual($this->expr->lt(1, 2), '1 < 2');
}
public function testLteReturnsValidSql() {
$this->assertEqual($this->expr->lte(1, 1), '1 <= 1');
}
/**
* WHERE OPERATORS
*/
public function testNotReturnsValidSql() {
$this->assertEqual($this->expr->not('id'), 'NOT(id)');
}
public function testInReturnsValidSql() {
$this->assertEqual($this->expr->in('id', array(1, 2)), 'id IN (1, 2)');
}
public function testIsNullReturnsValidSql() {
$this->assertEqual($this->expr->isNull('type'), 'type IS NULL');
}
public function testIsNotNullReturnsValidSql() {
$this->assertEqual($this->expr->isNotNull('type'), 'type IS NOT NULL');
}
public function testBetweenReturnsValidSql() {
$this->assertEqual($this->expr->between('age', 12, 14), 'age BETWEEN 12 AND 14');
}
}
......@@ -30,143 +30,37 @@
* @since 1.0
* @version $Revision$
*/
class Doctrine_Expression_TestCase extends Doctrine_UnitTestCase {
class Doctrine_Expression_TestCase extends Doctrine_UnitTestCase
{
public function prepareTables()
{
$this->tables = array('ExpressionTest');
parent::prepareTables();
}
public function prepareData()
{
}
public function testSavingWithAnExpression()
{
/**
* AGGREGATE FUNCTIONS
*/
public function testAvgReturnsValidSql() {
$this->expr = new Doctrine_Expression_Mock();
$e = new ExpressionTest();
$this->assertEqual($this->expr->avg('id'), 'AVG(id)');
}
public function testCountReturnsValidSql() {
$this->assertEqual($this->expr->count('id'), 'COUNT(id)');
}
public function testMaxReturnsValidSql() {
$this->assertEqual($this->expr->max('id'), 'MAX(id)');
}
public function testMinReturnsValidSql() {
$this->assertEqual($this->expr->min('id'), 'MIN(id)');
}
public function testSumReturnsValidSql() {
$this->assertEqual($this->expr->sum('id'), 'SUM(id)');
}
public function testRegexpImplementedOnlyAtDriverLevel() {
try {
$this->expr->regexp('[abc]');
$this->fail();
} catch(Doctrine_Expression_Exception $e) {
$this->pass();
}
}
public function testSoundexImplementedOnlyAtDriverLevel() {
try {
$this->expr->soundex('arnold');
$this->fail();
} catch(Doctrine_Expression_Exception $e) {
$this->pass();
}
}
/**
* TIME FUNCTIONS
*/
public function testNowReturnsValidSql() {
$this->assertEqual($this->expr->now(), 'NOW()');
}
/**
* STRING FUNCTIONS
*/
public function testUpperReturnsValidSql() {
$this->assertEqual($this->expr->upper('id', 3), 'UPPER(id)');
}
public function testLowerReturnsValidSql() {
$this->assertEqual($this->expr->lower('id'), 'LOWER(id)');
}
public function testLengthReturnsValidSql() {
$this->assertEqual($this->expr->length('id'), 'LENGTH(id)');
}
public function testLtrimReturnsValidSql() {
$this->assertEqual($this->expr->ltrim('id'), 'LTRIM(id)');
}
public function testLocateReturnsValidSql() {
$this->assertEqual($this->expr->locate('id', 3), 'LOCATE(id, 3)');
}
public function testConcatReturnsValidSql() {
$this->assertEqual($this->expr->concat('id', 'type'), 'CONCAT(id, type)');
}
public function testSubstringReturnsValidSql() {
$this->assertEqual($this->expr->substring('id', 3), 'SUBSTRING(id FROM 3)');
$this->assertEqual($this->expr->substring('id', 3, 2), 'SUBSTRING(id FROM 3 FOR 2)');
}
$e->name = new Doctrine_Expression("CONCAT('some', 'one')");
/**
* MATH FUNCTIONS
*/
public function testRoundReturnsValidSql() {
$this->assertEqual($this->expr->round(2.3), 'ROUND(2.3, 0)');
$e->save();
$this->assertEqual($this->expr->round(2.3, 1), 'ROUND(2.3, 1)');
}
public function testModReturnsValidSql() {
$this->assertEqual($this->expr->mod(2, 3), 'MOD(2, 3)');
}
public function testSubReturnsValidSql() {
$this->assertEqual($this->expr->sub(array(2, 3)), '(2 - 3)');
}
public function testMulReturnsValidSql() {
$this->assertEqual($this->expr->mul(array(2, 3)), '(2 * 3)');
}
public function testAddReturnsValidSql() {
$this->assertEqual($this->expr->add(array(2, 3)), '(2 + 3)');
}
public function testDivReturnsValidSql() {
$this->assertEqual($this->expr->div(array(2, 3)), '(2 / 3)');
}
/**
* ASSERT OPERATORS
*/
$e->refresh();
public function testEqReturnsValidSql() {
$this->assertEqual($this->expr->eq(1, 1), '1 = 1');
}
public function testNeqReturnsValidSql() {
$this->assertEqual($this->expr->neq(1, 2), '1 <> 2');
}
public function testGtReturnsValidSql() {
$this->assertEqual($this->expr->gt(2, 1), '2 > 1');
$this->assertEqual($e->name, 'someone');
}
public function testGteReturnsValidSql() {
$this->assertEqual($this->expr->gte(1, 1), '1 >= 1');
}
public function testLtReturnsValidSql() {
$this->assertEqual($this->expr->lt(1, 2), '1 < 2');
}
public function testLteReturnsValidSql() {
$this->assertEqual($this->expr->lte(1, 1), '1 <= 1');
}
/**
* WHERE OPERATORS
*/
public function testNotReturnsValidSql() {
$this->assertEqual($this->expr->not('id'), 'NOT(id)');
}
public function testInReturnsValidSql() {
$this->assertEqual($this->expr->in('id', array(1, 2)), 'id IN (1, 2)');
}
public function testIsNullReturnsValidSql() {
$this->assertEqual($this->expr->isNull('type'), 'type IS NULL');
}
public function testIsNotNullReturnsValidSql() {
$this->assertEqual($this->expr->isNotNull('type'), 'type IS NOT NULL');
}
public function testBetweenReturnsValidSql() {
$this->assertEqual($this->expr->between('age', 12, 14), 'age BETWEEN 12 AND 14');
}
class ExpressionTest extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string');
$this->hasColumn('amount', 'integer');
}
}
class Doctrine_Expression_Mock extends Doctrine_Expression { }
......@@ -94,7 +94,6 @@ class Doctrine_UnitTestCase extends UnitTestCase
switch($e[1]) {
case 'Export':
case 'Import':
case 'Expression':
case 'Transaction':
case 'DataDict':
case 'Sequence':
......
......@@ -140,6 +140,7 @@ $test->addTestCase(new Doctrine_Import_Sqlite_TestCase());
// Expression module (not yet fully tested)
$test->addTestCase(new Doctrine_Expression_TestCase());
$test->addTestCase(new Doctrine_Expression_Driver_TestCase());
$test->addTestCase(new Doctrine_Expression_Firebird_TestCase());
$test->addTestCase(new Doctrine_Expression_Informix_TestCase());
$test->addTestCase(new Doctrine_Expression_Mysql_TestCase());
......
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