From 7327d3b69e58c16468aec7c463efe88075660a27 Mon Sep 17 00:00:00 2001 From: doctrine Date: Sun, 23 Apr 2006 08:12:01 +0000 Subject: [PATCH] Custom primary key column support --- classes/Collection.class.php | 18 +++- classes/Collection/Batch.class.php | 10 +- classes/DB.class.php | 4 +- classes/DQL/Parser.class.php | 29 +++--- classes/DataDict.class.php | 2 +- classes/Identifier.class.php | 20 ++++ classes/Manager.class.php | 33 ++++-- classes/Record.class.php | 124 +++++++++++++++-------- classes/Relation.class.php | 23 ++++- classes/Session.class.php | 52 ++++------ classes/Session/Mysql.class.php | 22 +--- classes/Table.class.php | 119 +++++++++++++++------- classes/Validator.class.php | 21 ++++ tests/CollectionOffsetTestCase.class.php | 2 +- tests/CollectionTestCase.class.php | 3 +- tests/DQLParserTestCase.class.php | 2 +- tests/IdentifierTestCase.class.php | 4 + tests/RecordTestCase.class.php | 5 +- tests/TableTestCase.class.php | 13 ++- tests/UnitTestCase.class.php | 17 ++-- tests/classes.php | 2 +- tests/run.php | 10 +- 22 files changed, 342 insertions(+), 193 deletions(-) create mode 100644 classes/Identifier.class.php create mode 100644 tests/IdentifierTestCase.class.php diff --git a/classes/Collection.class.php b/classes/Collection.class.php index bc591a109..be27af3f8 100644 --- a/classes/Collection.class.php +++ b/classes/Collection.class.php @@ -59,9 +59,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator public function getTable() { return $this->table; } + /** + * whether or not an offset batch has been expanded + * @return boolean + */ public function isExpanded($offset) { return isset($this->expanded[$offset]); } + /** + * whether or not this collection is expandable + * @return boolean + */ public function isExpandable() { return $this->expandable; } @@ -175,7 +183,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $ids = $this->getPrimaryKeys(); if( ! empty($ids)) { - $where[] = "id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")"; + $where[] = $this->table->getIdentifier()." NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")"; $params = array_merge($params,$ids); } @@ -191,7 +199,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $table = $fk->getTable(); $graph = new Doctrine_DQL_Parser($table->getSession()); - $q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)"; + $q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$table->getIdentifier()." IN ($query)"; } } @@ -291,9 +299,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator */ public function getPrimaryKeys() { $list = array(); + $name = $this->table->getIdentifier(); + foreach($this->data as $record): - if(is_array($record) && isset($record['id'])) { - $list[] = $record['id']; + if(is_array($record) && isset($record[$name])) { + $list[] = $record[$name]; } else { $list[] = $record->getID(); } diff --git a/classes/Collection/Batch.class.php b/classes/Collection/Batch.class.php index 16b090c5f..243a4e76a 100644 --- a/classes/Collection/Batch.class.php +++ b/classes/Collection/Batch.class.php @@ -53,13 +53,14 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { return false; $id = $record->getID(); + $identifier = $this->table->getIdentifier(); foreach($this->data as $key => $v) { if(is_object($v)) { if($v->getID() == $id) break; - } elseif(is_array($v["id"])) { - if($v["id"] == $id) + } elseif(is_array($v[$identifier])) { + if($v[$identifier] == $id) break; } } @@ -77,7 +78,7 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { if(is_object($this->data[$i])) $id = $this->data[$i]->getID(); elseif(is_array($this->data[$i])) - $id = $this->data[$i]["id"]; + $id = $this->data[$i][$identifier]; $a[$i] = $id; @@ -87,11 +88,10 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { $pk = $this->table->getPrimaryKeys(); $query = $this->table->getQuery()." WHERE "; - $query .= ($c > 1)?$pk[0]." IN (":$pk[0]." = "; + $query .= ($c > 1)?$identifier." IN (":$pk[0]." = "; $query .= substr(str_repeat("?, ",count($a)),0,-2); $query .= ($c > 1)?") ORDER BY ".$pk[0]." ASC":""; - $stmt = $this->table->getSession()->execute($query,array_values($a)); foreach($a as $k => $id) { diff --git a/classes/DB.class.php b/classes/DB.class.php index 4ec7219b0..6345907d1 100644 --- a/classes/DB.class.php +++ b/classes/DB.class.php @@ -66,9 +66,9 @@ class Doctrine_DB extends PDO implements Countable, IteratorAggregate { try { $this->queries[] = $query; $time = microtime(); - + $stmt = parent::query($query); - + $this->exectimes[] = (microtime() - $time); return $stmt; } catch(PDOException $e) { diff --git a/classes/DQL/Parser.class.php b/classes/DQL/Parser.class.php index 7b601bcb6..f5a227829 100644 --- a/classes/DQL/Parser.class.php +++ b/classes/DQL/Parser.class.php @@ -348,7 +348,7 @@ class Doctrine_DQL_Parser { * remove duplicated data rows and map data into objects */ foreach($data as $key => $row): - if(empty($row) || empty($row['id'])) + if(empty($row)) continue; $key = ucwords($key); @@ -725,23 +725,24 @@ class Doctrine_DQL_Parser { $reference = implode(".",$a); $objTable = $this->session->getTable(end($a)); $where = $objTable->getTableName().".".$field." ".$operator." ".$value; + if(count($a) > 1 && isset($a[1])) { $root = $a[0]; $fk = $this->tnames[$root]->getForeignKey($a[1]); if($fk instanceof Doctrine_Association) { $asf = $fk->getAssociationFactory(); switch($fk->getType()): - case Doctrine_Table::ONE_AGGREGATE: - case Doctrine_Table::ONE_COMPOSITE: + case Doctrine_Relation::ONE_AGGREGATE: + case Doctrine_Relation::ONE_COMPOSITE: break; - case Doctrine_Table::MANY_AGGREGATE: - case Doctrine_Table::MANY_COMPOSITE: + case Doctrine_Relation::MANY_AGGREGATE: + case Doctrine_Relation::MANY_COMPOSITE: $b = array_shift($a); $b = array_shift($a); $graph = new Doctrine_DQL_Parser($this->session); $graph->parseQuery("FROM $b-l WHERE $where"); - $where = $this->tnames[$root]->getTableName().".id IN (SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (".$graph->getQuery()."))"; + $where = $this->tnames[$root]->getTableName().".".$this->tnames[$root]->getIdentifier()." IN (SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (".$graph->getQuery()."))"; break; endswitch; } else @@ -782,15 +783,15 @@ class Doctrine_DQL_Parser { if($fk instanceof Doctrine_ForeignKey || $fk instanceof Doctrine_LocalKey) { switch($fk->getType()): - case Doctrine_Table::ONE_AGGREGATE: - case Doctrine_Table::ONE_COMPOSITE: + case Doctrine_Relation::ONE_AGGREGATE: + case Doctrine_Relation::ONE_COMPOSITE: $this->where[] = "(".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign().")"; $this->from[$tname] = true; $this->from[$tname2] = true; break; - case Doctrine_Table::MANY_AGGREGATE: - case Doctrine_Table::MANY_COMPOSITE: + case Doctrine_Relation::MANY_AGGREGATE: + case Doctrine_Relation::MANY_COMPOSITE: $this->join[$tname] = "LEFT JOIN ".$tname2." ON ".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign(); $this->joined[] = $tname2; $this->from[$tname] = true; @@ -800,12 +801,12 @@ class Doctrine_DQL_Parser { $asf = $fk->getAssociationFactory(); switch($fk->getType()): - case Doctrine_Table::ONE_AGGREGATE: - case Doctrine_Table::ONE_COMPOSITE: + case Doctrine_Relation::ONE_AGGREGATE: + case Doctrine_Relation::ONE_COMPOSITE: break; - case Doctrine_Table::MANY_AGGREGATE: - case Doctrine_Table::MANY_COMPOSITE: + case Doctrine_Relation::MANY_AGGREGATE: + case Doctrine_Relation::MANY_COMPOSITE: //$this->addWhere("SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (SELECT ".$fk->getTable()->getComponentName().")"); $this->from[$tname] = true; diff --git a/classes/DataDict.class.php b/classes/DataDict.class.php index fdea7f90b..779fa6408 100644 --- a/classes/DataDict.class.php +++ b/classes/DataDict.class.php @@ -16,7 +16,7 @@ class Doctrine_DataDict { public function createTable($tablename, $columns) { foreach($columns as $name => $args) { - $r[] = $name." ".$this->getADOType($args[0],$args[1])." ".$args[2]; + $r[] = $name." ".$this->getADOType($args[0],$args[1])." ".str_replace("|"," ",$args[2]); } diff --git a/classes/Identifier.class.php b/classes/Identifier.class.php new file mode 100644 index 000000000..6b30fba5d --- /dev/null +++ b/classes/Identifier.class.php @@ -0,0 +1,20 @@ + diff --git a/classes/Manager.class.php b/classes/Manager.class.php index 521be18e8..3854353c2 100644 --- a/classes/Manager.class.php +++ b/classes/Manager.class.php @@ -6,7 +6,9 @@ require_once("EventListener.class.php"); * @package Doctrine ORM * @url www.phpdoctrine.com * @license LGPL - * @version 1.0 alpha + * + * Doctrine_Manager is the base component of all doctrine based projects. + * It opens and keeps track of all sessions (database connections). */ class Doctrine_Manager extends Doctrine_Configurable implements Countable, IteratorAggregate { /** @@ -26,7 +28,6 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera */ private $root; - /** * constructor */ @@ -63,13 +64,16 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } } /** - * @return string the root directory of Doctrine + * returns the root directory of Doctrine + * @return string */ final public function getRoot() { return $this->root; } /** - * getInstance this class uses the singleton pattern + * getInstance + * this class uses the singleton pattern + * @return Doctrine_Manager */ final public static function getInstance() { static $instance; @@ -80,10 +84,12 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } /** - * openSession open a new session and save it to Doctrine_Manager->sessions - * @param PDO $pdo PDO database driver - * @param string $name name of the session, if empty numeric key is used - * @return Doctrine_Session the opened session object + * openSession + * opens a new session and saves it to Doctrine_Manager->sessions + * + * @param PDO $pdo PDO database driver + * @param string $name name of the session, if empty numeric key is used + * @return Doctrine_Session */ final public function openSession(PDO $pdo, $name = null) { // initialize the default attributes @@ -158,7 +164,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } /** * setCurrentSession - * @param mixed $key the session key + * @param mixed $key the session key * @throws InvalidKeyException * @return void */ @@ -171,13 +177,14 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } /** * count - * @return integer the number of open sessions + * @return integer the number of open sessions */ public function count() { return count($this->sessions); } /** * getIterator + * returns an ArrayIterator that iterates through open sessions * @return ArrayIterator */ public function getIterator() { @@ -185,7 +192,9 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } /** * getCurrentSession - * @return object Doctrine_Session + * returns the current session + * @throws Doctrine_Session_Exception if there are no open sessions + * @return Doctrine_Session */ final public function getCurrentSession() { $i = $this->currIndex; @@ -196,6 +205,8 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera } /** * __toString + * returns a string representation of this object + * @return string */ public function __toString() { $r[] = "
";
diff --git a/classes/Record.class.php b/classes/Record.class.php
index d6751c03e..808f38732 100644
--- a/classes/Record.class.php
+++ b/classes/Record.class.php
@@ -117,6 +117,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
     
             self::$index++;
 
+            $keys = $this->table->getPrimaryKeys();
 
             if( ! $exists) {
                 // listen the onPreCreate event
@@ -151,26 +152,15 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
                 else
                     $this->loaded = true;
 
-                // id property is protected
-                $keys = $this->table->getPrimaryKeys();
-                if(count($keys) == 1) {
-                    $this->id = $this->data[$keys[0]];
-                } else {
-                    /**
-                    $this->id = array();
-                    foreach($keys as $key) {
-                        $this->id[] = $this->data[$key];
-                    }
-                    */
-                }
-    
+                $this->prepareIdentifiers();
+
                 // listen the onLoad event
                 $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this);
             }
             // add data access object to registry
             $this->table->getRepository()->add($this);
 
-            unset($this->data['id']);
+
 
             $this->table->setData(array());
         }
@@ -189,6 +179,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
     }
     /**
      * isLoaded
+     * whether or not this object has been fully loaded
+     * @return boolean
      */
     public function isLoaded() {
         return $this->loaded;                          	
@@ -221,6 +213,22 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
 
         return $cols;
     }
+    /**
+     * @return void
+     */
+    public function prepareIdentifiers() {
+        switch($this->table->getIdentifierType()):
+            case Doctrine_Identifier::AUTO_INCREMENT:
+            case Doctrine_Identifier::SEQUENCE:
+                $name = $this->table->getIdentifier();
+
+                if(isset($this->data[$name]))
+                    $this->id = $this->data[$name];
+
+                unset($this->data[$name]);
+            break;
+        endswitch;
+    }
     /**
      * this method is automatically called when this Doctrine_Record is serialized
      */
@@ -269,9 +277,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
 
         $this->cleanData();
 
-
-        unset($this->data['id']);
-
+        //unset($this->data['id']);
+        
         $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onWakeUp($this);
 
     }
@@ -322,10 +329,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
 
         $query          = $this->table->getQuery()." WHERE ".implode(" = ? && ",$this->table->getPrimaryKeys())." = ?";
         $this->data     = $this->table->getSession()->execute($query,array($this->getID()))->fetch(PDO::FETCH_ASSOC);
-        unset($this->data["id"]);
+
         $this->modified = array();
         $this->cleanData();
 
+        $this->prepareIdentifiers();
+
         $this->loaded   = true;
         $this->state    = Doctrine_Record::STATE_CLEAN;
 
@@ -338,15 +347,17 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
      */
     final public function factoryRefresh() {
         $data = $this->table->getData();
+        $id   = $this->id;
+        
+        $this->prepareIdentifiers();
 
-        if($this->id != $data["id"])
+        if($this->id != $id)
             throw new Doctrine_Refresh_Exception();
 
         $this->data     = $data;
 
         $this->cleanData();
 
-        unset($this->data["id"]);
         $this->state    = Doctrine_Record::STATE_CLEAN;
         $this->modified = array();
         $this->loaded   = true;
@@ -404,7 +415,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
             }
             return $this->data[$name];
         }
-        if($name == "id")
+        if($name == $this->table->getIdentifier())
             return $this->id;
 
         if( ! isset($this->references[$name]))
@@ -479,21 +490,21 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
             if($fk instanceof Doctrine_ForeignKey || 
                $fk instanceof Doctrine_LocalKey) {
                 switch($fk->getType()):
-                    case Doctrine_Table::MANY_COMPOSITE:
-                    case Doctrine_Table::MANY_AGGREGATE:
+                    case Doctrine_Relation::MANY_COMPOSITE:
+                    case Doctrine_Relation::MANY_AGGREGATE:
                         // one-to-many relation found
                         if( ! ($value instanceof Doctrine_Collection))
                             throw new Doctrine_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
 
                         $value->setReference($this,$fk);
                     break;
-                    case Doctrine_Table::ONE_COMPOSITE:
-                    case Doctrine_Table::ONE_AGGREGATE:
+                    case Doctrine_Relation::ONE_COMPOSITE:
+                    case Doctrine_Relation::ONE_AGGREGATE:
                         // one-to-one relation found
                         if( ! ($value instanceof Doctrine_Record))
                             throw new Doctrine_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references.");
 
-                        if($fk->getLocal() == "id") {
+                        if($fk->getLocal() == $this->table->getIdentifier()) {
                             $this->references[$name]->set($fk->getForeign(),$this);
                         } else {
                             $this->set($fk->getLocal(),$value);
@@ -561,6 +572,28 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
         }
         return $a;
     }
+    /**
+     * returns an array of modified fields and values with data preparation
+     * adds column aggregation inheritance and converts Records into primary key values
+     *
+     * @return array
+     */
+    final public function getPrepared() {
+        $a = array();
+
+        foreach($this->table->getInheritanceMap() as $k => $v) {
+            $this->set($k,$v);                                                       	
+        }
+
+        foreach($this->modified as $k => $v) {
+            if($this->data[$v] instanceof Doctrine_Record) {
+                $this->data[$v] = $this->data[$v]->getID();
+            }
+            $a[$v] = $this->data[$v];
+        }
+
+        return $a;
+    }
     /**
      * this class implements countable interface
      * @return integer                      the number of columns
@@ -589,10 +622,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
 
             if($fk instanceof Doctrine_Association) {
                 switch($fk->getType()):
-                    case Doctrine_Table::MANY_COMPOSITE:
+                    case Doctrine_Relation::MANY_COMPOSITE:
 
                     break;
-                    case Doctrine_Table::MANY_AGGREGATE:
+                    case Doctrine_Relation::MANY_AGGREGATE:
                         $asf     = $fk->getAssociationFactory();
                         if(isset($this->references[$name])) {
 
@@ -623,12 +656,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
                      $fk instanceof Doctrine_LocalKey) {
                 
                 switch($fk->getType()):
-                    case Doctrine_Table::ONE_COMPOSITE:
+                    case Doctrine_Relation::ONE_COMPOSITE:
                         if(isset($this->originals[$name]) && $this->originals[$name]->getID() != $this->references[$name]->getID())
                             $this->originals[$name]->delete();
                     
                     break;
-                    case Doctrine_Table::MANY_COMPOSITE:
+                    case Doctrine_Relation::MANY_COMPOSITE:
                         if(isset($this->references[$name])) {
                             $new = $this->references[$name];
 
@@ -808,8 +841,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
             case Doctrine_Record::STATE_TDIRTY:
             case Doctrine_Record::STATE_TCLEAN:
 
-                if($type == Doctrine_Table::ONE_COMPOSITE || 
-                   $type == Doctrine_Table::ONE_AGGREGATE) {
+                if($type == Doctrine_Relation::ONE_COMPOSITE || 
+                   $type == Doctrine_Relation::ONE_AGGREGATE) {
 
                     // ONE-TO-ONE
                     $this->references[$name] = $table->create();
@@ -833,8 +866,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
             case Doctrine_Record::STATE_CLEAN:
             case Doctrine_Record::STATE_PROXY:
                  switch($fk->getType()):
-                    case Doctrine_Table::ONE_COMPOSITE:
-                    case Doctrine_Table::ONE_AGGREGATE:
+                    case Doctrine_Relation::ONE_COMPOSITE:
+                    case Doctrine_Relation::ONE_AGGREGATE:
                         // ONE-TO-ONE
                         $id      = $this->get($local);
 
@@ -855,7 +888,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
                                 $this->references[$name] = $table->create();
                                 $this->references[$name]->set($fk->getForeign(), $this);
                             } else {
-                                $coll = $graph->query("FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?", array($id));
+                                $dql  = "FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?";
+                                $coll = $graph->query($dql, array($id));
                                 $this->references[$name] = $coll[0];
                                 $this->references[$name]->set($fk->getForeign(), $this);
                             }
@@ -864,7 +898,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
                     default:
                         // ONE-TO-MANY
                         if($fk instanceof Doctrine_ForeignKey) {
-                                    $id      = $this->get($local);
+                            $id      = $this->get($local);
                             $query = "FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?";
                             $coll = $graph->query($query,array($id));
     
@@ -880,7 +914,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
                             $query   = "SELECT ".$foreign." FROM ".$asf->getTableName()." WHERE ".$local." = ?";
         
                             $graph   = new Doctrine_DQL_Parser($table->getSession());
-                            $query   = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
+                            $query   = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$table->getIdentifier()." IN ($query)";
 
                             $coll    = $graph->query($query, array($this->getID()));
         
@@ -898,32 +932,32 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
      * @param string $fkField
      * @return void
      */
-    final public function ownsOne($componentName,$foreignKey, $localKey = "id") {
-        $this->table->bind($componentName,$foreignKey,Doctrine_Table::ONE_COMPOSITE, $localKey);
+    final public function ownsOne($componentName,$foreignKey, $localKey = null) {
+        $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_COMPOSITE, $localKey);
     }
     /**
      * @param string $objTableName
      * @param string $fkField
      * @return void
      */
-    final public function ownsMany($componentName,$foreignKey, $localKey = "id") {
-        $this->table->bind($componentName,$foreignKey,Doctrine_Table::MANY_COMPOSITE, $localKey);
+    final public function ownsMany($componentName,$foreignKey, $localKey = null) {
+        $this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_COMPOSITE, $localKey);
     }
     /**
      * @param string $objTableName
      * @param string $fkField
      * @return void
      */
-    final public function hasOne($componentName,$foreignKey, $localKey = "id") {
-        $this->table->bind($componentName,$foreignKey,Doctrine_Table::ONE_AGGREGATE, $localKey);
+    final public function hasOne($componentName,$foreignKey, $localKey = null) {
+        $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_AGGREGATE, $localKey);
     }
     /**
      * @param string $objTableName
      * @param string $fkField
      * @return void
      */
-    final public function hasMany($componentName,$foreignKey, $localKey = "id") {
-        $this->table->bind($componentName,$foreignKey,Doctrine_Table::MANY_AGGREGATE, $localKey);
+    final public function hasMany($componentName,$foreignKey, $localKey = null) {
+        $this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_AGGREGATE, $localKey);
     }
     /**
      * setInheritanceMap
diff --git a/classes/Relation.class.php b/classes/Relation.class.php
index e43c87910..3b9fd2ad2 100644
--- a/classes/Relation.class.php
+++ b/classes/Relation.class.php
@@ -10,6 +10,28 @@
  *
  */
 class Doctrine_Relation {
+    /**
+     * RELATION CONSTANTS
+     */
+
+    /**
+     * constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
+     */
+    const ONE_AGGREGATE         = 0;
+    /**
+     * constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
+     */
+    const ONE_COMPOSITE         = 1;
+    /**
+     * constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
+     */
+    const MANY_AGGREGATE        = 2;
+    /**
+     * constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
+     */
+    const MANY_COMPOSITE        = 3;
+    
+    
     /**
      * @var Doctrine_Table $table     foreign factory
      */
@@ -39,7 +61,6 @@ class Doctrine_Relation {
         $this->type     = $type;
     }
     /**
-     * @see Doctrine_Table::BIND_ONE, Doctrine_Table::BIND_MANY
      * @return integer              bind type 1 or 0
      */
     public function getType() {
diff --git a/classes/Session.class.php b/classes/Session.class.php
index b63dfe01a..2cb376588 100644
--- a/classes/Session.class.php
+++ b/classes/Session.class.php
@@ -47,7 +47,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
      * @var array $tables                   an array containing all the initialized Doctrine_Table objects
      *                                      keys representing Doctrine_Table component names and values as Doctrine_Table objects
      */
-    protected $tables         = array();
+    protected $tables       = array();
     /**
      * @var Doctrine_Validator $validator   transaction validator
      */
@@ -299,7 +299,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
         }
     }
     /**
-     * clear -- clears the whole registry
+     * clear        
+     * clears the whole registry
      * @return void
      */
     public function clear() {
@@ -415,7 +416,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
         if(empty($this->insert))
             return false;
         
-        
+
 
         foreach($this->insert as $name => $inserts) {
             if( ! isset($inserts[0]))
@@ -427,11 +428,11 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
             $increment = false;
             $id        = null;
             $keys      = $table->getPrimaryKeys();
-            if(count($keys) == 1 && $keys[0] == "id") {
+            if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
 
                 // record uses auto_increment column
 
-                $sql  = "SELECT MAX(id) FROM ".$record->getTable()->getTableName();
+                $sql  = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName();
                 $stmt = $this->dbh->query($sql);
                 $data = $stmt->fetch(PDO::FETCH_NUM);
                 $id   = $data[0];
@@ -474,10 +475,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
             $keys      = $table->getPrimaryKeys();
             $tablename = $table->getTableName();
 
-            if(count($keys) == 1 && $keys[0] == "id") {
+            if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
                 // record uses auto_increment column
 
-                $sql    = "SELECT MAX(id) FROM ".$tablename;
+                $sql    = "SELECT MAX(".$table->getIdentifier().") FROM ".$tablename;
                 $stmt   = $this->dbh->query($sql);
                 $data   = $stmt->fetch(PDO::FETCH_NUM);
                 $values[$tablename] = $data[0];
@@ -521,14 +522,16 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
     public function bulkDelete() {
         foreach($this->delete as $name => $deletes) {
             $record = false;
-            $ids = array();
+            $ids    = array();
             foreach($deletes as $k => $record) {
                 $ids[] = $record->getID();
                 $record->setID(null);
             }
             if($record instanceof Doctrine_Record) {
+                $table  = $record->getTable();
+
                 $params  = substr(str_repeat("?, ",count($ids)),0,-2);
-                $query   = "DELETE FROM ".$record->getTable()->getTableName()." WHERE id IN(".$params.")";
+                $query   = "DELETE FROM ".$record->getTable()->getTableName()." WHERE ".$table->getIdentifier()." IN(".$params.")";
                 $this->execute($query,$ids);
 
                 $record->getTable()->getCache()->deleteMultiple($ids);
@@ -592,8 +595,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
             if($fk instanceof Doctrine_ForeignKey ||
                $fk instanceof Doctrine_LocalKey) {
                 switch($fk->getType()):
-                    case Doctrine_Table::ONE_COMPOSITE:
-                    case Doctrine_Table::MANY_COMPOSITE:
+                    case Doctrine_Relation::ONE_COMPOSITE:
+                    case Doctrine_Relation::MANY_COMPOSITE:
                         $local = $fk->getLocal();
                         $foreign = $fk->getForeign();
 
@@ -630,11 +633,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
      */
     private function update(Doctrine_Record $record) {
         $array = $record->getModified();
+
         if(empty($array))
             return false;
 
-
-
         $set   = array();
         foreach($array as $name => $value):
                 $set[] = $name." = ?";
@@ -668,26 +670,16 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
      * @return boolean
      */
     private function insert(Doctrine_Record $record,$id = null) {
-        $array = $record->getModified();
+        $array = $record->getPrepared();
+
         if(empty($array))
             return false;
 
-
-        foreach($record->getTable()->getInheritanceMap() as $k=>$v):
-            $array[$k] = $v;
-        endforeach;
-
         $seq = $record->getTable()->getSequenceName();
         if( ! empty($seq)) {
-            $id = $this->getNextID($seq);
-            $array["id"] = $id;
-        }
-
-        foreach($array as $k => $value) {
-            if($value instanceof Doctrine_Record) {
-                $array[$k] = $value->getID();
-                $record->set($k,$value->getID());
-            }
+            $id             = $this->getNextID($seq);
+            $name           = $record->getTable()->getIdentifier();
+            $array[$name]   = $id;
         }
 
         if(isset($this->validator)) {
@@ -717,8 +709,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
     final public function deleteComposites(Doctrine_Record $record) {
         foreach($record->getTable()->getForeignKeys() as $fk) {
             switch($fk->getType()):
-                case Doctrine_Table::ONE_COMPOSITE:
-                case Doctrine_Table::MANY_COMPOSITE:
+                case Doctrine_Relation::ONE_COMPOSITE:
+                case Doctrine_Relation::MANY_COMPOSITE:
                     $obj = $record->get($fk->getTable()->getComponentName());
                     $obj->delete();
                 break;
diff --git a/classes/Session/Mysql.class.php b/classes/Session/Mysql.class.php
index e26789976..a6cb44ef9 100644
--- a/classes/Session/Mysql.class.php
+++ b/classes/Session/Mysql.class.php
@@ -48,10 +48,10 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
             $keys      = $table->getPrimaryKeys();
             $tablename = $table->getTableName();
 
-            if(count($keys) == 1 && $keys[0] == "id") {
+            if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
                 // record uses auto_increment column
 
-                $sql[]    = "SELECT MAX(".$tablename.".id) as $tablename FROM ".$tablename;
+                $sql[]    = "SELECT MAX(".$tablename.".".$table->getIdentifier().") as $tablename FROM ".$tablename;
                 $values[$tablename] = 0;
                 $array[] = $tablename;
             }
@@ -85,11 +85,11 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
             $increment = false;
             $id        = null;
             $keys      = $table->getPrimaryKeys();
-            if(count($keys) == 1 && $keys[0] == "id") {
+            if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
 
                 // record uses auto_increment column
 
-                $sql  = "SELECT MAX(id) FROM ".$record->getTable()->getTableName();
+                $sql  = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName();
                 $stmt = $this->getDBH()->query($sql);
                 $data = $stmt->fetch(PDO::FETCH_NUM);
                 $id   = $data[0];
@@ -111,20 +111,8 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
                     $id++;
                 }
 
+                $array = $record->getPrepared();
 
-                $array = $record->getModified();
-
-                foreach($record->getTable()->getInheritanceMap() as $k=>$v):
-                    $array[$k] = $v;
-                endforeach;
-
-                foreach($array as $k => $value) {
-                    if($value instanceof Doctrine_Record) {
-                        $array[$k] = $value->getID();
-                        $record->set($k,$value->getID());
-                    }
-                }
-                
                 if(isset($this->validator)) {
                     if( ! $this->validator->validateRecord($record)) {
                         continue;
diff --git a/classes/Table.class.php b/classes/Table.class.php
index cabc9e9ba..aa85a4898 100644
--- a/classes/Table.class.php
+++ b/classes/Table.class.php
@@ -12,23 +12,6 @@ require_once("Configurable.class.php");
  * @version     1.0 alpha
  */
 class Doctrine_Table extends Doctrine_Configurable {
-    /**
-     * constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
-     */
-    const ONE_AGGREGATE         = 0;
-    /**
-     * constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
-     */
-    const ONE_COMPOSITE         = 1;
-    /**
-     * constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
-     */
-    const MANY_AGGREGATE        = 2;
-    /**
-     * constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
-     */
-    const MANY_COMPOSITE        = 3;
-
     /**
      * @var boolean $isNewEntry                         whether ot not this table created a new record or not, used only internally
      */
@@ -46,9 +29,13 @@ class Doctrine_Table extends Doctrine_Configurable {
      */
     private $primaryKeys      = array();
     /**
-     * @var integer $primaryType
+     * @var mixed $identifier
      */
-    private $primaryType;
+    private $identifier;
+    /**
+     * @var integer $identifierType
+     */
+    private $identifierType;
     /**
      * @var string $query                               cached simple query
      */
@@ -117,7 +104,7 @@ class Doctrine_Table extends Doctrine_Configurable {
             throw new Doctrine_Exception("Couldn't find class $name");
 
         $record = new $name($this);
-        $record->setUp();
+
 
         $names = array();
 
@@ -151,14 +138,44 @@ class Doctrine_Table extends Doctrine_Configurable {
 
                 switch(count($this->primaryKeys)):
                     case 0:
-                        $this->columns = array_merge(array("id" => array("integer",11,"AUTOINCREMENT PRIMARY")), $this->columns);
+                        $this->columns = array_merge(array("id" => array("integer",11,"autoincrement|primary")), $this->columns);
                         $this->primaryKeys[] = "id";
-                    break;
-                    case 1:
-
+                        $this->identifier = "id";
+                        $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
                     break;
                     default:
+                        foreach($this->primaryKeys as $pk) {
+                            $o = $this->columns[$pk][2];
+                            $e = explode("|",$o);
+                            $found = false;
 
+
+                            foreach($e as $option) {
+                                if($found)
+                                    break;
+
+                                $e2 = explode(":",$option);
+
+                                switch(strtolower($e2[0])):
+                                    case "unique":
+                                        $this->identifierType = Doctrine_Identifier::UNIQUE;
+                                        $found = true;
+                                    break;
+                                    case "autoincrement":
+                                        $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
+                                        $found = true;
+                                    break;
+                                    case "seq":
+                                        $this->identifierType = Doctrine_Identifier::SEQUENCE;
+                                        $found = true;
+                                    break;
+                                endswitch;
+                            }
+                            if( ! isset($this->identifierType))
+                                $this->identifierType = Doctrine_Identifier::NORMAL;
+                                 
+                            $this->identifier = $pk;
+                        }
                 endswitch;
 
                 if($this->getAttribute(Doctrine::ATTR_CREATE_TABLES)) {
@@ -170,6 +187,8 @@ class Doctrine_Table extends Doctrine_Configurable {
         } else {
             throw new Doctrine_Exception("Class '$name' has no table definition.");
         }
+        
+        $record->setUp();
 
         // save parents
         array_pop($names);
@@ -216,6 +235,18 @@ class Doctrine_Table extends Doctrine_Configurable {
             $this->primaryKeys[] = $name;
         }
     }
+    /**
+     * @return mixed
+     */
+    final public function getIdentifier() {
+        return $this->identifier;
+    }
+    /**
+     * @return integer
+     */
+    final public function getIdentifierType() {
+        return $this->identifierType;
+    }
     /**
      * hasColumn
      * @return boolean
@@ -274,8 +305,8 @@ class Doctrine_Table extends Doctrine_Configurable {
             try {
             $fk = $this->getForeignKey($k);
             switch($fk->getType()):
-                case Doctrine_Table::ONE_COMPOSITE:
-                case Doctrine_Table::MANY_COMPOSITE:
+                case Doctrine_Relation::ONE_COMPOSITE:
+                case Doctrine_Relation::MANY_COMPOSITE:
                     $n = $fk->getTable()->getComponentName();
                     $array[] = $name.".".$n;
                     $e = $fk->getTable()->getCompositePaths();
@@ -323,7 +354,9 @@ class Doctrine_Table extends Doctrine_Configurable {
         
         // is reference table used?
         if($e[0] != $name && $e[0] == $this->name)
-            $this->bound[$name] = array($field,Doctrine_Table::MANY_COMPOSITE);
+            $this->bound[$name] = array($field,Doctrine_Relation::MANY_COMPOSITE);
+
+
 
         $this->bound[$name] = array($field,$type,$localKey);
     }
@@ -361,31 +394,42 @@ class Doctrine_Table extends Doctrine_Configurable {
             return $this->foreignKeys[$name];
 
         if(isset($this->bound[$name])) {
-            $type    = $this->bound[$name][1];
+
             $field   = $this->bound[$name][0];
+            $type    = $this->bound[$name][1];
+            $local   = $this->bound[$name][2];
             $e       = explode(".",$field);
             $objTable = $this->session->getTable($name);
 
             switch($e[0]):
                 case $name:
+                    if( ! isset($local))
+                        $local = $this->identifier;
+
                     // ONE-TO-MANY or ONE-TO-ONE
-                    $foreignKey = new Doctrine_ForeignKey($objTable,$this->bound[$name][2],$e[1],$type);
+                    $foreignKey = new Doctrine_ForeignKey($objTable,$local,$e[1],$type);
                 break;
                 case $this->name:
                     // ONE-TO-ONE
 
-                    if($type <= Doctrine_Table::ONE_COMPOSITE)
-                        $foreignKey = new Doctrine_LocalKey($objTable,$e[1],$this->bound[$name][2],$type);
-                    else
+                    if($type <= Doctrine_Relation::ONE_COMPOSITE) {
+                        if( ! isset($local))
+                            $local = $objTable->getIdentifier();
+
+                        $foreignKey = new Doctrine_LocalKey($objTable,$e[1],$local,$type);
+                    } else
                         throw new Doctrine_Mapping_Exception();
                 break;
                 default:
                     if(in_array($e[0], $this->parents)) {
                         // ONE-TO-ONE
 
-                        if($type <= Doctrine_Table::ONE_COMPOSITE)
-                            $foreignKey = new Doctrine_LocalKey($objTable,$e[1],$this->bound[$name][2],$type);
-                        else
+                        if($type <= Doctrine_Relation::ONE_COMPOSITE) {
+                            if( ! isset($local))
+                                $local = $objTable->getIdentifier();
+
+                            $foreignKey = new Doctrine_LocalKey($objTable,$e[1],$local,$type);
+                        } else
                             throw new Doctrine_Mapping_Exception();
                     } else {
                         // POSSIBLY MANY-TO-MANY
@@ -400,7 +444,8 @@ class Doctrine_Table extends Doctrine_Configurable {
 
                             }
                         }
-
+                        if( ! isset($local))
+                            $local = $this->identifier;
 
                         $e2    = explode(".",$bound[0]);
 
@@ -409,7 +454,7 @@ class Doctrine_Table extends Doctrine_Configurable {
 
                         $associationTable = $this->session->getTable($e2[0]);
 
-                        $this->foreignKeys[$e2[0]] = new Doctrine_ForeignKey($associationTable,$this->bound[$name][2],$e2[1],Doctrine_Table::MANY_COMPOSITE);
+                        $this->foreignKeys[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE);
 
                         $foreignKey         = new Doctrine_Association($objTable,$associationTable,$e2[1],$e[1],$type);
                     }
diff --git a/classes/Validator.class.php b/classes/Validator.class.php
index 3646d59bc..6cc9ee398 100644
--- a/classes/Validator.class.php
+++ b/classes/Validator.class.php
@@ -1,8 +1,27 @@
 stack;
     }
     /**
+     * returns the type of loosely typed variable
      * @param mixed $var
      */
     public static function gettype($var) {
diff --git a/tests/CollectionOffsetTestCase.class.php b/tests/CollectionOffsetTestCase.class.php
index 3213a06cf..3236a207d 100644
--- a/tests/CollectionOffsetTestCase.class.php
+++ b/tests/CollectionOffsetTestCase.class.php
@@ -40,7 +40,7 @@ class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase {
 
 
         $this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 1);
-        $users = $this->session->query("FROM User-b, User.Phonenumber-o WHERE User.id = 5");
+        $users = $this->session->query("FROM User-b, User.Phonenumber-o WHERE User.".$this->objTable->getIdentifier()." = 5");
 
         $this->assertEqual(count($users), 1);
 
diff --git a/tests/CollectionTestCase.class.php b/tests/CollectionTestCase.class.php
index bef7e954f..2860d87ca 100644
--- a/tests/CollectionTestCase.class.php
+++ b/tests/CollectionTestCase.class.php
@@ -37,7 +37,8 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
 
         $this->assertTrue($coll[2]->getState() == Doctrine_Record::STATE_PROXY);
 
-        $generator = new Doctrine_IndexGenerator("id");
+
+        $generator = new Doctrine_IndexGenerator($this->objTable->getIdentifier());
         $coll->setGenerator($generator);
         $generator = $coll->getGenerator();
         $this->assertEqual($generator->getIndex($this->old), 4);
diff --git a/tests/DQLParserTestCase.class.php b/tests/DQLParserTestCase.class.php
index f5f1ae85f..de2218817 100644
--- a/tests/DQLParserTestCase.class.php
+++ b/tests/DQLParserTestCase.class.php
@@ -168,7 +168,7 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
         $this->assertEqual($users->count(),8);
 
         $users = $graph->query("FROM User-b WHERE User.name LIKE '%Jack%'");
-        $this->assertTrue($graph->getQuery() == "SELECT entity.id AS User__id FROM entity WHERE (entity.name LIKE '%Jack%') AND (entity.type = 0)");
+        $this->assertEqual($graph->getQuery(), "SELECT entity.id AS User__id FROM entity WHERE (entity.name LIKE '%Jack%') AND (entity.type = 0)");
         $this->assertEqual($users->count(),0);
 
 
diff --git a/tests/IdentifierTestCase.class.php b/tests/IdentifierTestCase.class.php
new file mode 100644
index 000000000..a697e2dd4
--- /dev/null
+++ b/tests/IdentifierTestCase.class.php
@@ -0,0 +1,4 @@
+
diff --git a/tests/RecordTestCase.class.php b/tests/RecordTestCase.class.php
index 92a8ad520..d334c1330 100644
--- a/tests/RecordTestCase.class.php
+++ b/tests/RecordTestCase.class.php
@@ -129,7 +129,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
         $e->code     = 1;
 
         // ADDING NEW RECORD
-
         $this->assertEqual($e->code,1);
         $this->assertEqual($e->file_md5, md5(0));
         $this->assertEqual($e->message, "user error");
@@ -163,10 +162,10 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
         $this->assertEqual($e2->Description[1]->file_md5, $e2->file_md5);
 
         $e->save();
-
+        
         $coll = $this->session->query("FROM Error-I");
         $e = $coll[0];
-        
+
 
         $this->assertEqual($e->code,1);
         $this->assertEqual($e->file_md5, md5(0));
diff --git a/tests/TableTestCase.class.php b/tests/TableTestCase.class.php
index 399e2c5a3..3929ae279 100644
--- a/tests/TableTestCase.class.php
+++ b/tests/TableTestCase.class.php
@@ -1,27 +1,30 @@
 session->getTable("User");
+    }
     public function testGetForeignKey() {
         $fk = $this->objTable->getForeignKey("Group");
         $this->assertTrue($fk instanceof Doctrine_Association);
         $this->assertTrue($fk->getTable() instanceof Doctrine_Table);
-        $this->assertTrue($fk->getType() == Doctrine_Table::MANY_AGGREGATE);
+        $this->assertTrue($fk->getType() == Doctrine_Relation::MANY_AGGREGATE);
         $this->assertTrue($fk->getLocal() == "user_id");
         $this->assertTrue($fk->getForeign() == "group_id");
 
         $fk = $this->objTable->getForeignKey("Email");
         $this->assertTrue($fk instanceof Doctrine_LocalKey);
         $this->assertTrue($fk->getTable() instanceof Doctrine_Table);
-        $this->assertTrue($fk->getType() == Doctrine_Table::ONE_COMPOSITE);
+        $this->assertTrue($fk->getType() == Doctrine_Relation::ONE_COMPOSITE);
         $this->assertTrue($fk->getLocal() == "email_id");
-        $this->assertTrue($fk->getForeign() == "id");
+        $this->assertTrue($fk->getForeign() == $fk->getTable()->getIdentifier());
 
 
         $fk = $this->objTable->getForeignKey("Phonenumber");
         $this->assertTrue($fk instanceof Doctrine_ForeignKey);
         $this->assertTrue($fk->getTable() instanceof Doctrine_Table);
-        $this->assertTrue($fk->getType() == Doctrine_Table::MANY_COMPOSITE);
-        $this->assertTrue($fk->getLocal() == "id");
+        $this->assertTrue($fk->getType() == Doctrine_Relation::MANY_COMPOSITE);
+        $this->assertTrue($fk->getLocal() == $this->objTable->getIdentifier());
         $this->assertTrue($fk->getForeign() == "entity_id");
     }
     public function testGetComponentName() {
diff --git a/tests/UnitTestCase.class.php b/tests/UnitTestCase.class.php
index e5565c0d8..f9c2f1e92 100644
--- a/tests/UnitTestCase.class.php
+++ b/tests/UnitTestCase.class.php
@@ -1,13 +1,6 @@
 manager   = Doctrine_Manager::getInstance();
         $this->manager->setAttribute(Doctrine::ATTR_CACHE, Doctrine::CACHE_NONE);
         $this->manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE);
+        
+        $this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account");
+        $tables = $this->tables;
+
+
+
         if($this->manager->count() > 0) {
             $this->session = $this->manager->getSession(0);
             $this->session->clear();
             $this->dbh     = $this->session->getDBH();
             $this->listener = $this->manager->getAttribute(Doctrine::ATTR_LISTENER);
+
         } else {
             $this->dbh     = Doctrine_DB::getConnection();
             $this->session = $this->manager->openSession($this->dbh);
@@ -50,8 +50,6 @@ class Doctrine_UnitTestCase extends UnitTestCase {
             $this->manager->setAttribute(Doctrine::ATTR_LISTENER, $this->listener);
         }
 
-        $this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account");
-        $tables = $this->tables;
         foreach($tables as $name) {
             $this->dbh->query("DROP TABLE IF EXISTS $name");
         }
@@ -62,6 +60,7 @@ class Doctrine_UnitTestCase extends UnitTestCase {
         }
 
 
+
         $this->objTable = $this->session->getTable("User");
         $this->repository = $this->objTable->getRepository();
         //$this->cache = $this->objTable->getCache();
diff --git a/tests/classes.php b/tests/classes.php
index 354a1b101..73eea2f40 100644
--- a/tests/classes.php
+++ b/tests/classes.php
@@ -6,6 +6,7 @@ class Entity extends Doctrine_Record {
         $this->ownsOne("Account","Account.entity_id");
     }
     public function setTableDefinition() {
+        $this->hasColumn("id","integer",20,"autoincrement|primary");
         $this->hasColumn("name","string",50);
         $this->hasColumn("loginname","string",20,"unique");
         $this->hasColumn("password","string",16);
@@ -84,7 +85,6 @@ class Groupuser extends Doctrine_Record {
         $this->hasColumn("user_id","integer");
     }
 }
-
 class Phonenumber extends Doctrine_Record { 
     public function setTableDefinition() {
         $this->hasColumn("phonenumber","string",20);
diff --git a/tests/run.php b/tests/run.php
index d4df74521..03e0e1a25 100644
--- a/tests/run.php
+++ b/tests/run.php
@@ -23,18 +23,19 @@ error_reporting(E_ALL);
 
 $test = new GroupTest("Doctrine Framework Unit Tests");
 
+
+$test->addTestCase(new Doctrine_TableTestCase());
+
+
 $test->addTestCase(new Doctrine_SessionTestCase());
 
-
 $test->addTestCase(new Doctrine_RecordTestCase());
 
-
-
 $test->addTestCase(new Doctrine_ValidatorTestCase());
 
 $test->addTestCase(new Doctrine_ManagerTestCase());
 
-$test->addTestCase(new Doctrine_TableTestCase());
+
 
 $test->addTestCase(new Doctrine_AccessTestCase());
 
@@ -57,7 +58,6 @@ $test->addTestCase(new Doctrine_CollectionTestCase());
 $test->addTestCase(new Doctrine_Collection_OffsetTestCase());
 $test->addTestCase(new Sensei_UnitTestCase());
 
-
 //$test->addTestCase(new Doctrine_Cache_FileTestCase());
 //$test->addTestCase(new Doctrine_Cache_SqliteTestCase());