/**
  * Parses a database schema.
  *
  * @param Database $database
  * @return integer
  */
 public function parse(Database $database)
 {
     $stmt = null;
     $searchPath = '?';
     $params = [$database->getSchema()];
     if (!$database->getSchema()) {
         $stmt = $this->dbh->query('SHOW search_path');
         $searchPathString = $stmt->fetchColumn();
         $params = [];
         $searchPath = explode(',', $searchPathString);
         foreach ($searchPath as &$path) {
             $params[] = $path;
             $path = '?';
         }
         $searchPath = implode(', ', $searchPath);
     }
     $stmt = $this->dbh->prepare("SELECT c.oid,\n            c.relname, n.nspname\n            FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)\n            WHERE c.relkind = 'r'\n            AND n.nspname NOT IN ('information_schema','pg_catalog')\n            AND n.nspname NOT LIKE 'pg_temp%'\n            AND n.nspname NOT LIKE 'pg_toast%'\n            AND n.nspname IN ({$searchPath})\n            ORDER BY relname");
     $stmt->execute($params);
     $tableWraps = array();
     // First load the tables (important that this happen before filling out details of tables)
     while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         $name = $row['relname'];
         $namespaceName = $row['nspname'];
         if ($name == $this->getMigrationTable()) {
             continue;
         }
         $oid = $row['oid'];
         $table = new Table($name);
         if ('public' !== $namespaceName) {
             $table->setSchema($namespaceName);
         }
         $table->setIdMethod($database->getDefaultIdMethod());
         $database->addTable($table);
         // Create a wrapper to hold these tables and their associated OID
         $wrap = new \stdClass();
         $wrap->table = $table;
         $wrap->oid = $oid;
         $tableWraps[] = $wrap;
     }
     // Now populate only columns.
     foreach ($tableWraps as $wrap) {
         $this->addColumns($wrap->table, $wrap->oid);
     }
     // Now add indexes and constraints.
     foreach ($tableWraps as $wrap) {
         $this->addForeignKeys($wrap->table, $wrap->oid);
         $this->addIndexes($wrap->table, $wrap->oid);
         $this->addPrimaryKey($wrap->table, $wrap->oid);
     }
     $this->addSequences($database);
     return count($tableWraps);
 }
Example #2
0
 /**
  *
  */
 public function parse(Database $database)
 {
     $stmt = $this->dbh->query('SELECT version() as ver');
     $nativeVersion = $stmt->fetchColumn();
     if (!$nativeVersion) {
         throw new EngineException('Failed to get database version');
     }
     $arrVersion = sscanf($nativeVersion, '%*s %d.%d');
     $version = sprintf('%d.%d', $arrVersion[0], $arrVersion[1]);
     // Clean up
     $stmt = null;
     $stmt = $this->dbh->query("SELECT c.oid,\n            c.relname, n.nspname\n            FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)\n            WHERE c.relkind = 'r'\n            AND n.nspname NOT IN ('information_schema','pg_catalog')\n            AND n.nspname NOT LIKE 'pg_temp%'\n            AND n.nspname NOT LIKE 'pg_toast%'\n            ORDER BY relname");
     $tableWraps = array();
     // First load the tables (important that this happen before filling out details of tables)
     while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         $name = $row['relname'];
         $namespacename = $row['nspname'];
         if ($name == $this->getMigrationTable()) {
             continue;
         }
         $oid = $row['oid'];
         $table = new Table($name);
         if ($namespacename != 'public') {
             $table->setSchema($namespacename);
         }
         $table->setIdMethod($database->getDefaultIdMethod());
         $database->addTable($table);
         // Create a wrapper to hold these tables and their associated OID
         $wrap = new \stdClass();
         $wrap->table = $table;
         $wrap->oid = $oid;
         $tableWraps[] = $wrap;
     }
     // Now populate only columns.
     foreach ($tableWraps as $wrap) {
         $this->addColumns($wrap->table, $wrap->oid, $version);
     }
     // Now add indexes and constraints.
     foreach ($tableWraps as $wrap) {
         $this->addForeignKeys($wrap->table, $wrap->oid, $version);
         $this->addIndexes($wrap->table, $wrap->oid, $version);
         $this->addPrimaryKey($wrap->table, $wrap->oid, $version);
     }
     // @TODO - Handle Sequences ...
     return count($tableWraps);
 }
Example #3
0
 /**
  * Adds a new table to this database.
  *
  * @param  Table|array $table
  * @return Table
  */
 public function addTable($table)
 {
     if (!$table instanceof Table) {
         $tbl = new Table();
         $tbl->setDatabase($this);
         $tbl->setSchema($this->getSchema());
         $tbl->loadMapping($table);
         return $this->addTable($tbl);
     }
     $table->setDatabase($this);
     if (isset($this->tablesByName[$table->getName()])) {
         throw new EngineException(sprintf('Table "%s" declared twice', $table->getName()));
     }
     if (null === $table->getSchema()) {
         $table->setSchema($this->getSchema());
     }
     $this->tables[] = $table;
     $this->tablesByName[$table->getName()] = $table;
     $this->tablesByLowercaseName[strtolower($table->getName())] = $table;
     $this->tablesByPhpName[$table->getPhpName()] = $table;
     $this->computeTableNamespace($table);
     if (null === $table->getPackage()) {
         $table->setPackage($this->getPackage());
     }
     return $table;
 }
 protected function parseTables(Database $database, Table $filterTable = null)
 {
     $sql = "\n        SELECT name\n        FROM sqlite_master\n        WHERE type='table'\n        %filter%\n        UNION ALL\n        SELECT name\n        FROM sqlite_temp_master\n        WHERE type='table'\n        %filter%\n        ORDER BY name;";
     $filter = '';
     if ($filterTable) {
         if ($schema = $filterTable->getSchema()) {
             $filter = sprintf(" AND name LIKE '%s§%%'", $schema);
         }
         $filter .= sprintf(" AND (name = '%s' OR name LIKE '%%§%1\$s')", $filterTable->getCommonName());
     } else {
         if ($schema = $database->getSchema()) {
             $filter = sprintf(" AND name LIKE '%s§%%'", $schema);
         }
     }
     $sql = str_replace('%filter%', $filter, $sql);
     $dataFetcher = $this->dbh->query($sql);
     // First load the tables (important that this happen before filling out details of tables)
     foreach ($dataFetcher as $row) {
         $tableName = $row[0];
         $tableSchema = '';
         if ('sqlite_' == substr($tableName, 0, 7)) {
             continue;
         }
         if (false !== ($pos = strpos($tableName, '§'))) {
             $tableSchema = substr($tableName, 0, $pos);
             $tableName = substr($tableName, $pos + 2);
         }
         $table = new Table($tableName);
         if ($filterTable && $filterTable->getSchema()) {
             $table->setSchema($filterTable->getSchema());
         } else {
             if (!$database->getSchema() && $tableSchema) {
                 //we have no schema to filter, but this belongs to one, so next
                 continue;
             }
         }
         if ($tableName === $this->getMigrationTable()) {
             continue;
         }
         $table->setIdMethod($database->getDefaultIdMethod());
         $database->addTable($table);
     }
 }
 /**
  * @dataProvider provideSchemaNames
  *
  */
 public function testGetNameWithPlatform($supportsSchemas, $schemaName, $expectedName)
 {
     $database = $this->getDatabaseMock($schemaName, array('platform' => $this->getPlatformMock($supportsSchemas)));
     $database->expects($supportsSchemas ? $this->once() : $this->never())->method('getSchemaDelimiter')->will($this->returnValue('.'));
     $table = new Table('books');
     $table->setSchema($schemaName);
     $table->setDatabase($database);
     $this->assertSame($expectedName, $table->getName());
 }
 protected function parseTables(&$tableWraps, Database $database, Table $filterTable = null)
 {
     $stmt = null;
     $params = [];
     $sql = "\n          SELECT c.oid, c.relname, n.nspname\n          FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)\n          WHERE c.relkind = 'r'\n            AND n.nspname NOT IN ('information_schema','pg_catalog')\n            AND n.nspname NOT LIKE 'pg_temp%'\n            AND n.nspname NOT LIKE 'pg_toast%'";
     if ($filterTable) {
         if ($schema = $filterTable->getSchema()) {
             $sql .= ' AND n.nspname = ?';
             $params[] = $schema;
         }
         $sql .= ' AND c.relname = ?';
         $params[] = $filterTable->getCommonName();
     } else {
         if (!$database->getSchema()) {
             $stmt = $this->dbh->query('SELECT current_schemas(false)');
             $searchPathString = substr($stmt->fetchColumn(), 1, -1);
             $params = [];
             $searchPath = explode(',', $searchPathString);
             foreach ($searchPath as &$path) {
                 $params[] = $path;
                 $path = '?';
             }
             $searchPath = implode(', ', $searchPath);
             $sql .= "\n            AND n.nspname IN ({$searchPath})";
         } elseif ($database->getSchema()) {
             $sql .= "\n            AND n.nspname = ?";
             $params[] = $database->getSchema();
         }
     }
     $sql .= "\n          ORDER BY relname";
     $stmt = $this->dbh->prepare($sql);
     $stmt->execute($params);
     // First load the tables (important that this happen before filling out details of tables)
     while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         $name = $row['relname'];
         $namespaceName = $row['nspname'];
         if ($name == $this->getMigrationTable()) {
             continue;
         }
         $oid = $row['oid'];
         $table = new Table($name);
         if ('public' !== $namespaceName) {
             $table->setSchema($namespaceName);
         }
         $table->setIdMethod($database->getDefaultIdMethod());
         $database->addTable($table);
         // Create a wrapper to hold these tables and their associated OID
         $wrap = new \stdClass();
         $wrap->table = $table;
         $wrap->oid = $oid;
         $tableWraps[] = $wrap;
     }
 }
Example #7
0
 public function testQualifiedName()
 {
     $table = new Table();
     $table->setSchema("foo");
     $table->setCommonName("bar");
     $this->assertEquals($table->getName(), "bar");
     $this->assertEquals($table->getCommonName(), "bar");
     $database = new Database();
     $database->addTable($table);
     $database->setPlatform(new NoSchemaPlatform());
     $this->assertEquals($table->getName(), "bar");
     $database->setPlatform(new SchemaPlatform());
     $this->assertEquals($table->getName(), "foo.bar");
 }
Example #8
0
 /**
  * An utility method to add a new table from an xml attribute.
  */
 public function addTable($data)
 {
     if ($data instanceof Table) {
         $tbl = $data;
         // alias
         if (isset($this->tablesByName[$tbl->getName()])) {
             throw new EngineException(sprintf('Table "%s" declared twice', $tbl->getName()));
         }
         $tbl->setDatabase($this);
         if ($tbl->getSchema() === null) {
             $tbl->setSchema($this->getSchema());
         }
         $this->tableList[] = $tbl;
         $this->tablesByName[$tbl->getName()] = $tbl;
         $this->tablesByLowercaseName[strtolower($tbl->getName())] = $tbl;
         $this->tablesByPhpName[$tbl->getPhpName()] = $tbl;
         if (strpos($tbl->getNamespace(), '\\') === 0) {
             $tbl->setNamespace(substr($tbl->getNamespace(), 1));
         } elseif ($namespace = $this->getNamespace()) {
             if ($tbl->getNamespace() === null) {
                 $tbl->setNamespace($namespace);
             } else {
                 $tbl->setNamespace($namespace . '\\' . $tbl->getNamespace());
             }
         }
         if ($tbl->getPackage() === null) {
             $tbl->setPackage($this->getPackage());
         }
         return $tbl;
     } else {
         $tbl = new Table();
         $tbl->setDatabase($this);
         $tbl->setSchema($this->getSchema());
         $tbl->loadFromXML($data);
         return $this->addTable($tbl);
         // call self w/ different param
     }
 }
 protected function parseTables(Database $database, $filterTable = null)
 {
     $sql = 'SHOW FULL TABLES';
     if ($filterTable) {
         if ($schema = $filterTable->getSchema()) {
             $sql .= ' FROM ' . $database->getPlatform()->doQuoting($schema);
         }
         $sql .= sprintf(" LIKE '%s'", $filterTable->getCommonName());
     } else {
         if ($schema = $database->getSchema()) {
             $sql .= ' FROM ' . $database->getPlatform()->doQuoting($schema);
         }
     }
     $dataFetcher = $this->dbh->query($sql);
     // First load the tables (important that this happen before filling out details of tables)
     $tables = array();
     foreach ($dataFetcher as $row) {
         $name = $row[0];
         $type = $row[1];
         if ($name == $this->getMigrationTable() || $type !== 'BASE TABLE') {
             continue;
         }
         $table = new Table($name);
         $table->setIdMethod($database->getDefaultIdMethod());
         if ($filterTable && $filterTable->getSchema()) {
             $table->setSchema($filterTable->getSchema());
         }
         $database->addTable($table);
         $tables[] = $table;
     }
 }
Example #10
0
 public function testAddTableWithSameNameOnDifferentSchema()
 {
     $db = new Database();
     $db->setPlatform(new PgsqlPlatform());
     $t1 = new Table('t1');
     $db->addTable($t1);
     $this->assertEquals('t1', $t1->getName());
     $t1b = new Table('t1');
     $t1b->setSchema('bis');
     $db->addTable($t1b);
     $this->assertEquals('bis.t1', $t1b->getName());
 }