diff --git a/Doctrine/DataDict.php b/Doctrine/DataDict.php index a93f2ae28..0f01fc7d0 100644 --- a/Doctrine/DataDict.php +++ b/Doctrine/DataDict.php @@ -34,15 +34,10 @@ class Doctrine_DataDict { foreach($columns as $name => $args) { if( ! is_array($args[2])) $args[2] = array(); - - $constraints = array(); - foreach($args[2] as $k => $v) { - if(is_string($k)) - $constraints[] = $k; - else - $constraints[] = $v; - } + unset($args[2]['default']); + + $constraints = array_keys($args[2]); $r[] = $name." ".$this->getADOType($args[0],$args[1])." ".implode(' ', $constraints); } diff --git a/Doctrine/Record.php b/Doctrine/Record.php index c0943398f..6c599e20e 100644 --- a/Doctrine/Record.php +++ b/Doctrine/Record.php @@ -188,6 +188,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite else $this->state = Doctrine_Record::STATE_TCLEAN; + // set the default values for this record + $this->setDefaultValues(); + // listen the onCreate event $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onCreate($this); @@ -233,6 +236,27 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite public function getOID() { return $this->oid; } + /** + * setDefaultValues + * sets the default values + * + * @param boolean $overwrite whether or not to overwrite the already set values + * @return boolean + */ + public function setDefaultValues($overwrite = false) { + if( ! $this->table->hasDefaultValues()) + return false; + + foreach($this->data as $column => $value) { + $default = $this->table->getDefaultValueOf($column); + + if($default === null) + $default = self::$null; + + if($value === self::$null || $overwrite) + $this->data[$column] = $default; + } + } /** * cleanData * modifies data array @@ -466,7 +490,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $id = array_values($id); $query = $this->table->getQuery()." WHERE ".implode(" = ? AND ",$this->table->getPrimaryKeys())." = ?"; - $this->data = $this->table->getConnection()->execute($query,$id)->fetch(PDO::FETCH_ASSOC); + $stmt = $this->table->getConnection()->execute($query,$id); + + $this->data = $stmt->fetch(PDO::FETCH_ASSOC); + if( ! $this->data) throw new Doctrine_Record_Exception('Failed to refresh. Record does not exist anymore'); diff --git a/Doctrine/Table.php b/Doctrine/Table.php index 7dddbad3f..eec7c0552 100644 --- a/Doctrine/Table.php +++ b/Doctrine/Table.php @@ -123,6 +123,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { * @var array $enum enum value arrays */ private $enum = array(); + /** + * @var boolean $hasDefaultValues whether or not this table has default values + */ + private $hasDefaultValues; @@ -176,7 +180,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { switch(count($this->primaryKeys)): case 0: - $this->columns = array_merge(array("id" => array("integer",11, array("autoincrement", "primary"))), $this->columns); + $this->columns = array_merge(array("id" => array("integer",11, array("autoincrement" => true, "primary" => true))), $this->columns); $this->primaryKeys[] = "id"; $this->identifier = "id"; $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; @@ -193,7 +197,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { $found = false; - foreach($e as $option) { + foreach($e as $option => $value) { if($found) break; @@ -279,13 +283,50 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { if(is_string($options)) $options = explode('|', $options); + foreach($options as $k => $option) { + if(is_numeric($k)) { + if( ! empty($option)) + $options[$option] = true; + + unset($options[$k]); + } + } + $this->columns[$name] = array($type,$length,$options); - if(in_array("primary",$options)) { + if(isset($options['primary'])) { $this->primaryKeys[] = $name; } + if(isset($options['default'])) { + $this->hasDefaultValues = true; + } } + /** + * hasDefaultValues + * returns true if this table has default values, otherwise false + * + * @return boolean + */ + public function hasDefaultValues() { + return $this->hasDefaultValues; + } + /** + * getDefaultValueOf + * returns the default value(if any) for given column + * + * @param string $column + * @return mixed + */ + public function getDefaultValueOf($column) { + if( ! isset($this->columns[$column])) + throw new Doctrine_Table_Exception("Couldn't get default value. Column ".$column." doesn't exist."); + if(isset($this->columns[$column][2]['default'])) { + + return $this->columns[$column][2]['default']; + } else + return null; + } /** * @return mixed */ diff --git a/Doctrine/adodb-hack/drivers/datadict-sqlite.inc.php b/Doctrine/adodb-hack/drivers/datadict-sqlite.inc.php index be04a42c6..9a1ac07f5 100644 --- a/Doctrine/adodb-hack/drivers/datadict-sqlite.inc.php +++ b/Doctrine/adodb-hack/drivers/datadict-sqlite.inc.php @@ -63,7 +63,7 @@ class ADODB2_sqlite extends ADODB_DataDict { return $suffix; } - function _TableSQL($tabname,$lines,$pkey,$tableoptions) + function _TableSQL($tabname, $lines,$pkey,$tableoptions) { $sql = array(); diff --git a/manual/codes/Getting started - Setting table definition - Default values.php b/manual/codes/Getting started - Setting table definition - Default values.php new file mode 100644 index 000000000..e69de29bb diff --git a/manual/docs/Getting started - Setting table definition - Default values.php b/manual/docs/Getting started - Setting table definition - Default values.php new file mode 100644 index 000000000..e69de29bb diff --git a/manual/documentation.php b/manual/documentation.php index df8eac1f1..d942b01f9 100644 --- a/manual/documentation.php +++ b/manual/documentation.php @@ -96,6 +96,7 @@ $menu = array("Getting started" => "Introduction", "Data types and lengths", "Constraints and validators", + "Default values", "Enum emulation" ), "Record identifiers" => array( diff --git a/tests/RecordTestCase.php b/tests/RecordTestCase.php index d636c7917..df7920e07 100644 --- a/tests/RecordTestCase.php +++ b/tests/RecordTestCase.php @@ -5,9 +5,82 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { public function prepareTables() { $this->tables[] = "enumTest"; + $this->tables[] = "fieldNameTest"; parent::prepareTables(); } + public function testEnumType() { + + $enum = new EnumTest(); + $enum->status = "open"; + $this->assertEqual($enum->status, "open"); + $enum->save(); + $this->assertEqual($enum->status, "open"); + $enum->refresh(); + $this->assertEqual($enum->status, "open"); + + $enum->status = "closed"; + + $this->assertEqual($enum->status, "closed"); + + $enum->save(); + $this->assertEqual($enum->status, "closed"); + $this->assertTrue(is_numeric($enum->id)); + $enum->refresh(); + $this->assertEqual($enum->status, "closed"); + } + + public function testEnumTypeWithCaseConversion() { + $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER); + + $enum = new EnumTest(); + + $enum->status = "open"; + $this->assertEqual($enum->status, "open"); + + $enum->save(); + $this->assertEqual($enum->status, "open"); + + $enum->refresh(); + $this->assertEqual($enum->status, "open"); + + $enum->status = "closed"; + + $this->assertEqual($enum->status, "closed"); + + $enum->save(); + $this->assertEqual($enum->status, "closed"); + + $enum->refresh(); + $this->assertEqual($enum->status, "closed"); + + $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); + } + + public function testFailingRefresh() { + $enum = $this->connection->getTable('EnumTest')->find(1); + + $this->dbh->query('DELETE FROM enum_test WHERE id = 1'); + + $f = false; + try { + $enum->refresh(); + } catch(Doctrine_Record_Exception $e) { + $f = true; + } + $this->assertTrue($f); + } + public function testDefaultValues() { + + $test = new FieldNameTest; + + $this->assertEqual($test->someColumn, 'some string'); + $this->assertEqual($test->someEnum, 'php'); + $this->assertEqual($test->someArray, array()); + $this->assertTrue(is_object($test->someObject)); + $this->assertEqual($test->someInt, 11); + } + public function testJoinTableSelfReferencingInsertingData() { $e = new Entity(); $e->name = "Entity test"; @@ -210,66 +283,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { } - public function testEnumType() { - - $enum = new EnumTest(); - $enum->status = "open"; - $this->assertEqual($enum->status, "open"); - $enum->save(); - $this->assertEqual($enum->status, "open"); - $enum->refresh(); - $this->assertEqual($enum->status, "open"); - - $enum->status = "closed"; - - $this->assertEqual($enum->status, "closed"); - - $enum->save(); - $this->assertEqual($enum->status, "closed"); - - $enum->refresh(); - $this->assertEqual($enum->status, "closed"); - } - - public function testEnumTypeWithCaseConversion() { - $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER); - - $enum = new EnumTest(); - - $enum->status = "open"; - $this->assertEqual($enum->status, "open"); - - $enum->save(); - $this->assertEqual($enum->status, "open"); - - $enum->refresh(); - $this->assertEqual($enum->status, "open"); - - $enum->status = "closed"; - - $this->assertEqual($enum->status, "closed"); - - $enum->save(); - $this->assertEqual($enum->status, "closed"); - - $enum->refresh(); - $this->assertEqual($enum->status, "closed"); - - $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); - } - public function testFailingRefresh() { - $enum = $this->connection->getTable('EnumTest')->find(1); - - $this->dbh->query('DELETE FROM enum_test WHERE id = 1'); - - $f = false; - try { - $enum->refresh(); - } catch(Doctrine_Record_Exception $e) { - $f = true; - } - $this->assertTrue($f); - } public function testSerialize() { $user = $this->connection->getTable("User")->find(4); @@ -918,5 +931,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { $user = $this->connection->getTable("User")->find(4); $this->assertTrue($user->getIterator() instanceof ArrayIterator); } + } ?> diff --git a/tests/classes.php b/tests/classes.php index 900e54b17..33132f873 100644 --- a/tests/classes.php +++ b/tests/classes.php @@ -19,11 +19,11 @@ class Entity extends Doctrine_Record { } class FieldNameTest extends Doctrine_Record { public function setTableDefinition() { - $this->hasColumn("someColumn", "string", 200); - $this->hasColumn("someEnum", "enum", 4); - $this->hasColumn("someArray", "array", 100); - $this->hasColumn("someObject", "array", 200); - $this->hasColumn("someInt", "integer"); + $this->hasColumn("someColumn", "string", 200, array('default' => 'some string')); + $this->hasColumn("someEnum", "enum", 4, array('default' => 'php')); + $this->hasColumn("someArray", "array", 100, array('default' => array())); + $this->hasColumn("someObject", "object", 200, array('default' => new stdClass)); + $this->hasColumn("someInt", "integer", 20, array('default' => 11)); $this->setEnumValues("someEnum", array('php', 'java', 'python')); diff --git a/tests/run.php b/tests/run.php index 0ff8d74d8..b8061c6bf 100644 --- a/tests/run.php +++ b/tests/run.php @@ -32,12 +32,12 @@ error_reporting(E_ALL); $test = new GroupTest("Doctrine Framework Unit Tests"); -$test->addTestCase(new Doctrine_AccessTestCase()); +$test->addTestCase(new Doctrine_RecordTestCase()); + +$test->addTestCase(new Doctrine_AccessTestCase()); $test->addTestCase(new Doctrine_EventListenerTestCase()); -$test->addTestCase(new Doctrine_RecordTestCase()); - $test->addTestCase(new Doctrine_TableTestCase()); $test->addTestCase(new Doctrine_ConnectionTestCase());