Changeset 3565

Show
Ignore:
Timestamp:
01/22/08 21:42:17 (18 months ago)
Author:
jwage
Message:

Connection refactoring to allow create/drop database functionality for sqlite. fixes #480

Location:
trunk
Files:
1 removed
16 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/Doctrine.php

    r3461 r3565  
    895895    public static function createDatabases($specifiedConnections = array()) 
    896896    { 
    897         if ( ! is_array($specifiedConnections)) { 
    898             $specifiedConnections = (array) $specifiedConnections; 
    899         } 
    900  
    901         $manager = Doctrine_Manager::getInstance(); 
    902         $connections = $manager->getConnections(); 
    903  
    904         $results = array(); 
    905  
    906         foreach ($connections as $name => $connection) { 
    907             if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
    908                 continue; 
    909             } 
    910  
    911             $info = $manager->parsePdoDsn($connection->getOption('dsn')); 
    912             $username = $connection->getOption('username'); 
    913             $password = $connection->getOption('password'); 
    914  
    915             // Make connection without database specified so we can create it 
    916             $connect = $manager->openConnection(new PDO($info['scheme'] . ':host=' . $info['host'], $username, $password), 'tmp_connection', false); 
    917  
    918             try { 
    919                 // Create database 
    920                 $connect->export->createDatabase($name); 
    921  
    922                 // Close the tmp connection with no database 
    923                 $manager->closeConnection($connect); 
    924  
    925                 // Close original connection 
    926                 $manager->closeConnection($connection); 
    927  
    928                 // Reopen original connection with newly created database 
    929                 $manager->openConnection(new PDO($info['dsn'], $username, $password), $name, true); 
    930  
    931                 $results[$name] = true; 
    932             } catch (Exception $e) { 
    933                 $results[$name] = false; 
    934             } 
    935         } 
    936  
    937         return $results; 
     897        return Doctrine_Manager::getInstance()->createDatabases($specifiedConnections); 
    938898    } 
    939899 
     
    948908    public static function dropDatabases($specifiedConnections = array()) 
    949909    { 
    950         if ( ! is_array($specifiedConnections)) { 
    951             $specifiedConnections = (array) $specifiedConnections; 
    952         } 
    953  
    954         $manager = Doctrine_Manager::getInstance(); 
    955  
    956         $connections = $manager->getConnections(); 
    957  
    958         $results = array(); 
    959  
    960         foreach ($connections as $name => $connection) { 
    961             if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
    962                 continue; 
    963             } 
    964  
    965             try { 
    966                 $connection->export->dropDatabase($connection->getDatabaseName()); 
    967  
    968                 $results[$name] = true; 
    969             } catch (Exception $e) { 
    970                 $results[$name] = false; 
    971             } 
    972         } 
    973  
    974         return $results; 
     910        return Doctrine_Manager::getInstance()->dropDatabases($specifiedConnections); 
    975911    } 
    976912 
  • trunk/lib/Doctrine/Connection.php

    r3517 r3565  
    7676     */ 
    7777    protected $_mappers = array(); 
     78     
     79    /** 
     80     * $_name 
     81     * 
     82     * Name of the connection 
     83     * 
     84     * @var string $_name 
     85     */ 
     86    protected $_name; 
    7887 
    7988    /** 
     
    307316    public function getName() 
    308317    { 
     318        return $this->_name; 
     319    } 
     320     
     321    public function setName($name) 
     322    { 
     323        $this->_name = $name; 
     324    } 
     325     
     326    public function getDriverName() 
     327    { 
    309328        return $this->driverName; 
    310329    } 
     
    341360                    break; 
    342361                default: 
    343                     $class = 'Doctrine_' . ucwords($name) . '_' . $this->getName(); 
     362                    $class = 'Doctrine_' . ucwords($name) . '_' . $this->getDriverName(); 
    344363                    $this->modules[$name] = new $class($this); 
    345364                } 
     
    13821401 
    13831402    /** 
     1403     * createDatabase 
     1404     * 
     1405     * @return void 
     1406     */ 
     1407    public function createDatabase() 
     1408    { 
     1409      $manager = $this->getManager(); 
     1410 
     1411      $info = $manager->parsePdoDsn($this->getOption('dsn')); 
     1412      $username = $this->getOption('username'); 
     1413      $password = $this->getOption('password'); 
     1414 
     1415      // Make connection without database specified so we can create it 
     1416      $connect = $manager->openConnection(new PDO($info['scheme'] . ':host=' . $info['host'], $username, $password), 'tmp_connection', false); 
     1417       
     1418      try { 
     1419          // Create database 
     1420          $connect->export->createDatabase($info['dbname']); 
     1421 
     1422          // Close the tmp connection with no database 
     1423          $manager->closeConnection($connect); 
     1424 
     1425          // Close original connection 
     1426          $manager->closeConnection($this); 
     1427 
     1428          // Reopen original connection with newly created database 
     1429          $manager->openConnection(new PDO($info['dsn'], $username, $password), $this->getName(), true); 
     1430 
     1431          return 'Successfully created database for connection "' . $this->getName() . '" named "' . $info['dbname'] . '"'; 
     1432      } catch (Exception $e) { 
     1433          return $e; 
     1434      } 
     1435    } 
     1436 
     1437    /** 
     1438     * dropDatabase 
     1439     * 
     1440     * @return void 
     1441     */ 
     1442    public function dropDatabase() 
     1443    { 
     1444      try { 
     1445          $info = $this->getManager()->parsePdoDsn($this->getOption('dsn')); 
     1446           
     1447          $this->export->dropDatabase($info['dbname']); 
     1448 
     1449          return 'Successfully dropped database for connection "' . $this->getName() . '" named "' . $info['dbname'] . '"'; 
     1450      } catch (Exception $e) { 
     1451          return $e; 
     1452      } 
     1453    } 
     1454 
     1455    /** 
    13841456     * returns a string representation of this object 
    13851457     * @return string 
  • trunk/lib/Doctrine/Connection/Sqlite.php

    r3499 r3565  
    9797 
    9898    /** 
    99      * getDatabaseFile 
     99     * createDatabase 
    100100     * 
    101      * @param string $name      the name of the database 
    102      * @return string 
     101     * @return void 
    103102     */ 
    104     public function getDatabaseFile($name) 
     103    public function createDatabase() 
    105104    { 
    106         return $name . '.db'; 
     105      try { 
     106          $manager = $this->getManager(); 
     107 
     108          $info = $manager->parseDsn($this->getOption('dsn')); 
     109 
     110          $this->export->createDatabase($info['database']); 
     111 
     112          return 'Successfully created database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"'; 
     113      } catch (Exception $e) { 
     114          return $e; 
     115      } 
     116    } 
     117 
     118    /** 
     119     * dropDatabase 
     120     * 
     121     * @return void 
     122     */ 
     123    public function dropDatabase() 
     124    { 
     125      try { 
     126          $info = $this->getManager()->parseDsn($this->getOption('dsn')); 
     127 
     128          $this->export->dropDatabase($info['database']); 
     129 
     130          return 'Successfully dropped database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"'; 
     131      } catch (Exception $e) { 
     132          return $e; 
     133      } 
    107134    } 
    108135} 
  • trunk/lib/Doctrine/Export.php

    r3500 r3565  
    10571057    /** 
    10581058     * exportClasses 
     1059     * 
     1060     * FIXME: This method is a big huge hack. The sql needs to be executed in the correct order. I have some stupid logic to  
     1061     * make sure they are in the right order. 
     1062     * 
    10591063     * method for exporting Doctrine_Record classes to a schema 
    10601064     * 
     
    10741078            if ( ! isset($connections[$connectionName])) { 
    10751079                $connections[$connectionName] = array(); 
    1076                 $connections[$connectionName]['creates'] = array(); 
     1080                $connections[$connectionName]['create_tables'] = array(); 
     1081                $connections[$connectionName]['create_sequences'] = array(); 
    10771082                $connections[$connectionName]['alters'] = array(); 
    10781083            } 
     
    10821087            // We need these to happen first 
    10831088            foreach ($sql as $key => $query) { 
    1084                 if (strstr($query, 'CREATE')) { 
    1085                     $connections[$connectionName]['creates'][] = $query; 
    1086                     // Unset the create from sql so we can have an array of everything else but creates 
     1089                if (strstr($query, 'CREATE TABLE')) { 
     1090                    $connections[$connectionName]['create_tables'][] = $query; 
     1091 
     1092                    unset($sql[$key]); 
     1093                } 
     1094 
     1095                if (strstr($query, 'CREATE SEQUENCE')) { 
     1096                    $connections[$connectionName]['create_sequences'][] = $query; 
     1097 
    10871098                    unset($sql[$key]); 
    10881099                } 
     
    10951106        $build = array(); 
    10961107        foreach ($connections as $connectionName => $sql) { 
    1097             $build[$connectionName] = array_merge($sql['creates'], $sql['alters']); 
     1108            $build[$connectionName] = array_merge($sql['create_tables'], $sql['create_sequences'], $sql['alters']); 
    10981109        } 
    10991110 
  • trunk/lib/Doctrine/Export/Sqlite.php

    r3500 r3565  
    3535{ 
    3636    /** 
     37     * dropDatabase 
     38     * 
    3739     * drop an existing database 
    3840     * 
    39      * @param string $name                  name of the database that should be dropped 
     41     * @param string $databaseFile          Path of the database that should be dropped 
    4042     * @throws Doctrine_Export_Exception    if the database file does not exist 
    4143     * @throws Doctrine_Export_Exception    if something failed during the removal of the database file 
    4244     * @return void 
    4345     */ 
    44     public function dropDatabase($name) 
    45     { 
    46         $databaseFile = $this->conn->getDatabaseFile($name); 
     46    public function dropDatabase($databaseFile) 
     47    { 
    4748        if ( ! @file_exists($databaseFile)) { 
    4849            throw new Doctrine_Export_Exception('database does not exist'); 
    4950        } 
     51 
    5052        $result = @unlink($databaseFile); 
     53 
    5154        if ( ! $result) { 
    5255            throw new Doctrine_Export_Exception('could not remove the database file'); 
    5356        } 
     57    } 
     58 
     59    /** 
     60     * createDatabase 
     61     * 
     62     * Create sqlite database file 
     63     * 
     64     * @param string $databaseFile  Path of the database that should be dropped 
     65     * @return void 
     66     */ 
     67    public function createDatabase($databaseFile) 
     68    { 
     69        return new PDO('sqlite:' . $databaseFile); 
    5470    } 
    5571 
  • trunk/lib/Doctrine/Manager.php

    r3517 r3565  
    313313        $className = $drivers[$driverName]; 
    314314        $conn = new $className($this, $adapter); 
     315        $conn->setName($name); 
    315316 
    316317        $this->_connections[$name] = $conn; 
     
    346347        $e = explode(';', $e[1]); 
    347348        foreach ($e as $string) { 
    348             list($key, $value) = explode('=', $string); 
    349             $parts[$key] = $value; 
    350         } 
    351          
     349            if ($string) { 
     350                $e2 = explode('=', $string); 
     351 
     352                if (isset($e2[0]) && isset($e2[1])) { 
     353                    list($key, $value) = $e2; 
     354                    $parts[$key] = $value; 
     355                } 
     356            } 
     357        } 
     358 
    352359        return $parts; 
    353360    } 
     
    361368    public function parseDsn($dsn) 
    362369    { 
    363         //fix linux sqlite dsn so that it will parse correctly 
    364         $dsn = str_replace("///", "/", $dsn); 
    365  
     370        // fix sqlite dsn so that it will parse correctly 
     371        $dsn = str_replace("////", "/", $dsn); 
     372        $dsn = str_replace("///c:/", "//c:/", $dsn); 
     373         
    366374        // silence any warnings 
    367375        $parts = @parse_url($dsn); 
     
    452460        } 
    453461 
    454  
    455462        return $parts; 
    456463    } 
     
    694701        } 
    695702        return $this->_connections[$i]; 
     703    } 
     704 
     705    /** 
     706     * createDatabases 
     707     * 
     708     * Creates databases for connections 
     709     * 
     710     * @param string $specifiedConnections Array of connections you wish to create the database for 
     711     * @return void 
     712     */ 
     713    public function createDatabases($specifiedConnections = array()) 
     714    { 
     715        if ( ! is_array($specifiedConnections)) { 
     716            $specifiedConnections = (array) $specifiedConnections; 
     717        } 
     718 
     719        $results = array(); 
     720 
     721        foreach ($this as $name => $connection) { 
     722            if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
     723                continue; 
     724            } 
     725 
     726            $results[$name] = $connection->createDatabase(); 
     727        } 
     728 
     729        return $results; 
     730    } 
     731 
     732    /** 
     733     * dropDatabases 
     734     * 
     735     * Drops databases for connections 
     736     * 
     737     * @param string $specifiedConnections Array of connections you wish to drop the database for 
     738     * @return void 
     739     */ 
     740    public function dropDatabases($specifiedConnections = array()) 
     741    { 
     742        if ( ! is_array($specifiedConnections)) { 
     743            $specifiedConnections = (array) $specifiedConnections; 
     744        } 
     745 
     746        $results = array(); 
     747 
     748        foreach ($this as $name => $connection) { 
     749            if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
     750                continue; 
     751            } 
     752 
     753            $results[$name] = $connection->dropDatabase(); 
     754        } 
     755 
     756        return $results; 
    696757    } 
    697758 
  • trunk/lib/Doctrine/Query/Tokenizer.php

    r3458 r3565  
    378378            } 
    379379        } 
    380         $term[$i - 1] = array($term[$i - 1], ''); 
     380 
     381        if (isset($term[$i - 1])) { 
     382            $term[$i - 1] = array($term[$i - 1], ''); 
     383        } 
    381384 
    382385        return $term; 
  • trunk/lib/Doctrine/Task/CreateDb.php

    r3458 r3565  
    4040        $results = Doctrine::createDatabases(); 
    4141         
    42         foreach ($results as $dbName => $bool) { 
    43             $msg = $bool ? 'Successfully created database named: "' . $dbName . '"':'Could not create database named: "' .$dbName . '"'; 
     42        foreach ($results as $name => $result) { 
     43            $msg = $result instanceof Exception ? 'Could not create database for connection: "' .$name . '." Failed with exception: ' . $result->getMessage():$result; 
    4444             
    4545            $this->notify($msg); 
  • trunk/lib/Doctrine/Task/DropDb.php

    r3458 r3565  
    4949        $results = Doctrine::dropDatabases(); 
    5050         
    51         foreach ($results as $dbName => $bool) { 
    52             $msg = $bool ? 'Successfully dropped database named: "' . $dbName . '"':'Could not drop database named: "' .$dbName . '"'; 
     51        foreach ($results as $name => $result) { 
     52            $msg = $result instanceof Exception ? 'Could not drop database for connection: "' .$name . '." Failed with exception: ' . $result->getMessage():$result; 
    5353             
    5454            $this->notify($msg); 
  • trunk/models/TreeLeaf.php

    r2353 r3565  
    77        $this->hasColumn('parent_id', 'integer'); 
    88    } 
     9 
    910    public function setUp()  
    1011    { 
    11         $this->hasOne('TreeLeaf as Parent', 'TreeLeaf.parent_id'); 
    12         $this->hasMany('TreeLeaf as Children', 'TreeLeaf.parent_id'); 
     12        $this->hasOne('TreeLeaf as Parent', array('local' => 'parent_id', 'foreign' => 'id')); 
     13        $this->hasMany('TreeLeaf as Children', array('local' => 'id', 'foreign' => 'parent_id')); 
    1314    } 
    1415} 
  • trunk/tests/Export/SqliteTestCase.php

    r3501 r3565  
    3333class Doctrine_Export_Sqlite_TestCase extends Doctrine_UnitTestCase 
    3434{ 
    35     public function testCreateDatabaseDoesNotExecuteSql() 
     35    public function testCreateDatabaseDoesNotExecuteSqlAndCreatesSqliteFile() 
    3636    { 
    37         try { 
    38             $this->export->createDatabase('db'); 
    39             $this->fail(); 
    40         } catch(Doctrine_Export_Exception $e) { 
    41             $this->pass(); 
    42         } 
     37        $this->export->createDatabase('sqlite.db'); 
     38         
     39        $this->assertTrue(file_exists('sqlite.db')); 
    4340    } 
    44     public function testDropDatabaseDoesNotExecuteSql() 
     41    public function testDropDatabaseDoesNotExecuteSqlAndDeletesSqliteFile() 
    4542    { 
    46         try { 
    47             $this->export->dropDatabase('db'); 
    48             $this->fail(); 
    49         } catch(Doctrine_Export_Exception $e) { 
    50             $this->pass(); 
    51         } 
     43        $this->export->dropDatabase('sqlite.db'); 
     44 
     45        $this->assertFalse(file_exists('sqlite.db')); 
    5246    } 
    5347    public function testCreateTableSupportsAutoincPks() 
     
    172166        $this->export->createTable('sometable', $fields, $options); 
    173167 
    174         //removed this assertion and inserted the two below 
    175 //        $this->assertEqual($this->adapter->pop(), 'CREATE TABLE sometable (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(4), INDEX myindex (id ASC, name DESC))'); 
    176  
    177168        $this->assertEqual($this->adapter->pop(),"CREATE INDEX myindex_idx ON sometable (id ASC, name DESC)"); 
    178169 
     
    180171 
    181172    } 
    182  
    183     /** 
    184     public function testExportSupportsEmulationOfCascadingDeletes() 
    185     { 
    186         $r = new ForeignKeyTest; 
    187  
    188         $this->assertEqual($this->adapter->pop(), 'COMMIT'); 
    189         $this->assertEqual($this->adapter->pop(), 'CREATE TRIGGER doctrine_foreign_key_test_cscd_delete AFTER DELETE ON foreign_key_test BEGIN DELETE FROM foreign_key_test WHERE parent_id = old.id;END;'); 
    190         $this->assertEqual($this->adapter->pop(), 'CREATE TABLE foreign_key_test (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(2147483647), code INTEGER, content VARCHAR(4000), parent_id INTEGER)'); 
    191         $this->assertEqual($this->adapter->pop(), 'BEGIN TRANSACTION'); 
    192     } 
    193     */ 
    194173} 
  • trunk/tests/ManagerTestCase.php

    r3071 r3565  
    6666        // It expects only // since it thinks it is parsing a url 
    6767        // The problem after that is that the dns is not valid when being passed to PDO 
    68         $sqlite = 'sqlite:///full/unix/path/to/file.db'; 
    69         $sqlitewin = 'sqlite://c:/full/windows/path/to/file.db'; 
     68        $sqlite = 'sqlite:////full/unix/path/to/file.db'; 
     69        $sqlitewin = 'sqlite:///c:/full/windows/path/to/file.db'; 
    7070         
    7171        $manager = Doctrine_Manager::getInstance(); 
  • trunk/tests/run.php

    r3503 r3565  
    154154 
    155155// Utility components 
    156 $plugins = new GroupTest('Plugin tests: View, Validator, Hook','plugins'); 
    157 //$utility->addTestCase(new Doctrine_PessimisticLocking_TestCase()); 
     156$plugins = new GroupTest('Plugin tests: View, Validator, Hook', 'plugins'); 
     157//$plugins->addTestCase(new Doctrine_PessimisticLocking_TestCase()); 
    158158//$plugins->addTestCase(new Doctrine_Plugin_TestCase()); 
    159159$plugins->addTestCase(new Doctrine_View_TestCase()); 
  • trunk/tests/Ticket/480TestCase.php

    r3493 r3565  
    4646    public function testInit() 
    4747    { 
    48                 $this->dbh = new Doctrine_Adapter_Mock('oracle'); 
    49                 $this->conn = Doctrine_Manager::getInstance()->openConnection($this->dbh); 
     48        $this->dbh = new Doctrine_Adapter_Mock('oracle'); 
     49        $this->conn = Doctrine_Manager::getInstance()->openConnection($this->dbh); 
    5050    } 
    5151 
  • trunk/tests/TreeStructureTestCase.php

    r2353 r3565  
    104104        $o4->save(); 
    105105 
    106         $o1->Children; 
    107106        $this->assertFalse(isset($o1->Parent)); 
     107        $this->assertTrue(isset($o2->Parent)); 
     108        $this->assertTrue($o2->Parent === $o1); 
     109        $this->assertFalse(isset($o4->Parent)); 
     110         
    108111        $this->assertTrue(count($o1->Children) == 2); 
    109112        $this->assertTrue(count($o1->get('Children')) == 2); 
    110113 
    111         $this->assertTrue(isset($o2->Parent)); 
    112         $this->assertTrue($o2->Parent === $o1); 
    113  
    114114        $this->assertTrue(count($o4->Children) == 0); 
    115         $this->assertFalse(isset($o4->Parent)); 
    116115    } 
    117116    public function testTreeStructureFetchingWorksWithDql() 
  • trunk/tools/sandbox/config.php.dist

    r3415 r3565  
    4343define('YAML_SCHEMA_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'schema'); 
    4444define('DB_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'sandbox.db'); 
    45 define('DSN', 'sqlite:' . DB_PATH); 
     45define('DSN', 'sqlite:///' . DB_PATH); 
    4646 
    4747require_once(DOCTRINE_PATH . DIRECTORY_SEPARATOR . 'Doctrine.php'); 
     
    4949spl_autoload_register(array('Doctrine', 'autoload')); 
    5050 
    51 $pdo = new PDO(DSN); 
    52 Doctrine_Manager::connection($pdo, 'sandbox'); 
     51Doctrine_Manager::connection(DSN, 'sandbox'); 
    5352 
    5453Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);