From 7529c4d9860ad7e93576d3548e074e86634d0366 Mon Sep 17 00:00:00 2001 From: zYne Date: Fri, 29 Dec 2006 11:03:19 +0000 Subject: [PATCH] added new import driver functionality --- lib/Doctrine/Import/Mysql.php | 126 +++++++++++++++++++--- lib/Doctrine/Import/Oracle.php | 187 ++++++++++++++++++++++++++------- lib/Doctrine/Import/Sqlite.php | 54 +++++++++- lib/Doctrine/Table.php | 1 + 4 files changed, 316 insertions(+), 52 deletions(-) diff --git a/lib/Doctrine/Import/Mysql.php b/lib/Doctrine/Import/Mysql.php index 18571bba8..86f5150b4 100644 --- a/lib/Doctrine/Import/Mysql.php +++ b/lib/Doctrine/Import/Mysql.php @@ -64,7 +64,22 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @return array */ public function listSequences($database = null) { - + $query = "SHOW TABLES"; + if (!is_null($database)) { + $query .= " FROM $database"; + } + $tableNames = $db->queryCol($query); + + $result = array(); + foreach ($tableNames as $tableName) { + if ($sqn = $this->_fixSequenceName($tableName, true)) { + $result[] = $sqn; + } + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists table constraints @@ -73,9 +88,48 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @return array */ public function listTableConstraints($table) { - $sql = 'select KCU.COLUMN_NAME as referencingColumn, TC.CONSTRAINT_NAME as constraintName, KCU.REFERENCED_TABLE_SCHEMA as referencedTableSchema, KCU.REFERENCED_TABLE_NAME as referencedTable, KCU.REFERENCED_COLUMN_NAME as referencedColumn from INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC inner JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU on TC.CONSTRAINT_NAME=KCU.CONSTRAINT_NAME and TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA and TC.TABLE_NAME=KCU.TABLE_NAME WHERE TC.TABLE_SCHEMA=database() AND TC.TABLE_NAME="'.$table.'" AND CONSTRAINT_TYPE="FOREIGN KEY"'; - - return $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); + $db =& $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $key_name = 'Key_name'; + $non_unique = 'Non_unique'; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $key_name = strtolower($key_name); + $non_unique = strtolower($non_unique); + } else { + $key_name = strtoupper($key_name); + $non_unique = strtoupper($non_unique); + } + } + + $table = $db->quoteIdentifier($table, true); + $query = "SHOW INDEX FROM $table"; + $indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($indexes)) { + return $indexes; + } + + $result = array(); + foreach ($indexes as $index_data) { + if (!$index_data[$non_unique]) { + if ($index_data[$key_name] !== 'PRIMARY') { + $index = $this->_fixIndexName($index_data[$key_name]); + } else { + $index = 'PRIMARY'; + } + if (!empty($index)) { + $result[$index] = true; + } + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); } /** * lists table constraints @@ -112,8 +166,36 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableIndexes($table) { - + public function listTableIndexes($table) + { + $key_name = 'Key_name'; + $non_unique = 'Non_unique'; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $key_name = strtolower($key_name); + $non_unique = strtolower($non_unique); + } else { + $key_name = strtoupper($key_name); + $non_unique = strtoupper($non_unique); + } + } + + $table = $db->quoteIdentifier($table, true); + $query = "SHOW INDEX FROM $table"; + $indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC); + + + $result = array(); + foreach ($indexes as $index_data) { + if ($index_data[$non_unique] && ($index = $this->_fixIndexName($index_data[$key_name]))) { + $result[$index] = true; + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); } /** * lists tables @@ -121,7 +203,8 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @param string|null $database * @return array */ - public function listTables($database = null) { + public function listTables($database = null) + { $sql = 'SHOW TABLES'; return $this->dbh->query($sql)->fetchAll(PDO::FETCH_COLUMN); @@ -132,7 +215,8 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableTriggers($table) { + public function listTableTriggers($table) + { } /** @@ -141,16 +225,18 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableViews($table) { - + public function listTableViews($table) + { + } /** * lists database users * * @return array */ - public function listUsers() { - + public function listUsers() + { + return $db->queryCol('SELECT DISTINCT USER FROM USER'); } /** * lists database views @@ -158,7 +244,19 @@ class Doctrine_Import_Mysql extends Doctrine_Import { * @param string|null $database * @return array */ - public function listViews($database = null) { - + public function listViews($database = null) + { + $query = 'SHOW FULL TABLES'; + if (!is_null($database)) { + $query.= ' FROM ' . $database; + } + $query.= " WHERE Table_type = 'VIEW'"; + + $result = $db->queryCol($query); + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } } diff --git a/lib/Doctrine/Import/Oracle.php b/lib/Doctrine/Import/Oracle.php index 9fc9f074a..bec2b3d1f 100644 --- a/lib/Doctrine/Import/Oracle.php +++ b/lib/Doctrine/Import/Oracle.php @@ -34,16 +34,48 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * * @return array */ - public function listDatabases() { + public function listDatabases() + { + if ( ! $this->conn->options['emulate_database']) { + return $this->conn->raiseError(Doctrine::ERROR_UNSUPPORTED, null, null, + 'database listing is only supported if the "emulate_database" option is enabled', __FUNCTION__); + } + if ($this->conn->options['database_name_prefix']) { + $query = 'SELECT SUBSTR(username, '; + $query.= (strlen($this->conn->options['database_name_prefix'])+1); + $query.= ") FROM sys.dba_users WHERE username LIKE '"; + $query.= $this->conn->options['database_name_prefix']."%'"; + } else { + $query = 'SELECT username FROM sys.dba_users'; + } + $result2 = $this->conn->standaloneQuery($query, array('text'), false); + $result = $result2->fetchCol(); + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + $result2->free(); + return $result; } /** * lists all availible database functions * * @return array */ - public function listFunctions() { - + public function listFunctions() + { + $query = "SELECT name FROM sys.user_source WHERE line = 1 AND type = 'FUNCTION'"; + $result = $this->conn->queryCol($query); + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists all database triggers @@ -51,7 +83,8 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string|null $database * @return array */ - public function listTriggers($database = null) { + public function listTriggers($database = null) + { } /** @@ -60,8 +93,19 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string|null $database * @return array */ - public function listSequences($database = null) { - + public function listSequences($database = null) + { + $query = "SELECT sequence_name FROM sys.user_sequences"; + $tableNames = $this->conn->queryCol($query); + + $result = array(); + foreach ($tableNames as $tableName) { + $result[] = $this->_fixSequenceName($tableName); + } + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists table constraints @@ -69,29 +113,49 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableConstraints($table) { - - } - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableColumns($table) { - $sql = "DESCRIBE $table"; - $result = $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); - $columns = array(); - foreach ($result as $key => $val) { - $description = array( - 'name' => $val['Field'], - 'notnull' => (bool) ($val['Null'] === ''), - 'type' => $val['Type'], - ); - $columns[$val['Field']] = new Doctrine_Schema_Column($description); + public function listTableConstraints($table) + { + + $table = $this->conn->quote($table, 'text'); + $query = 'SELECT index_name name FROM user_constraints'; + $query.= ' WHERE table_name='.$table.' OR table_name='.strtoupper($table); + $constraints = $this->conn->queryCol($query); + + $result = array(); + foreach ($constraints as $constraint) { + $constraint = $this->_fixIndexName($constraint); + if (!empty($constraint)) { + $result[$constraint] = true; + } } - return $columns; + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_change_key_case($result, $this->conn->options['field_case']); + } + return array_keys($result); + } + /** + * lists table constraints + * + * @param string $table database table name + * @return array + */ + public function listTableColumns($table) + { + + $table = $this->conn->quote($table, 'text'); + $query = 'SELECT column_name FROM user_tab_columns'; + $query.= ' WHERE table_name='.$table.' OR table_name='.strtoupper($table).' ORDER BY column_id'; + $result = $this->conn->queryCol($query); + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists table constraints @@ -100,7 +164,27 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @return array */ public function listTableIndexes($table) { - + + $table = $this->conn->quote($table, 'text'); + $query = 'SELECT index_name name FROM user_indexes'; + $query.= ' WHERE table_name='.$table.' OR table_name='.strtoupper($table); + $query.= ' AND generated=' .$this->conn->quote('N', 'text'); + $indexes = $this->conn->queryCol($query, 'text'); + + $result = array(); + foreach ($indexes as $index) { + $index = $this->_fixIndexName($index); + if (!empty($index)) { + $result[$index] = true; + } + } + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_change_key_case($result, $this->conn->options['field_case']); + } + return array_keys($result); } /** * lists tables @@ -108,8 +192,18 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string|null $database * @return array */ - public function listTables($database = null) { - return $this->dbh->fetchCol('SELECT table_name FROM all_tables ORDER BY table_name'); + public function listTables($database = null) + { + + $query = 'SELECT table_name FROM sys.user_tables'; + $result = $this->conn->queryCol($query); + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists table triggers @@ -117,7 +211,8 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableTriggers($table) { + public function listTableTriggers($table) + { } /** @@ -126,7 +221,8 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string $table database table name * @return array */ - public function listTableViews($table) { + public function listTableViews($table) + { } /** @@ -134,8 +230,18 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * * @return array */ - public function listUsers() { - + public function listUsers() + { + + if ($this->conn->options['emulate_database'] && $this->conn->options['database_name_prefix']) { + $query = 'SELECT SUBSTR(username, '; + $query.= (strlen($this->conn->options['database_name_prefix'])+1); + $query.= ") FROM sys.dba_users WHERE username NOT LIKE '"; + $query.= $this->conn->options['database_name_prefix']."%'"; + } else { + $query = 'SELECT username FROM sys.dba_users'; + } + return $this->conn->queryCol($query); } /** * lists database views @@ -143,7 +249,16 @@ class Doctrine_Import_Oracle extends Doctrine_Import { * @param string|null $database * @return array */ - public function listViews($database = null) { - + public function listViews($database = null) + { + $query = 'SELECT view_name FROM sys.user_views'; + $result = $this->conn->queryCol($query); + + if ($this->conn->options['portability'] & Doctrine::PORTABILITY_FIX_CASE + && $this->conn->options['field_case'] == CASE_LOWER + ) { + $result = array_map(($this->conn->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } } diff --git a/lib/Doctrine/Import/Sqlite.php b/lib/Doctrine/Import/Sqlite.php index 79f2fc6ef..bdd1b3e4f 100644 --- a/lib/Doctrine/Import/Sqlite.php +++ b/lib/Doctrine/Import/Sqlite.php @@ -62,7 +62,26 @@ class Doctrine_Import_Sqlite extends Doctrine_Import { * @return array */ public function listSequences($database = null) { - + $db =& $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; + $table_names = $db->queryCol($query); + if (PEAR::isError($table_names)) { + return $table_names; + } + $result = array(); + foreach ($table_names as $table_name) { + if ($sqn = $this->_fixSequenceName($table_name, true)) { + $result[] = $sqn; + } + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; } /** * lists table constraints @@ -71,7 +90,38 @@ class Doctrine_Import_Sqlite extends Doctrine_Import { * @return array */ public function listTableConstraints($table) { - + $db =& $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table = $db->quote($table, 'text'); + $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(tbl_name)='.strtolower($table); + } else { + $query.= "tbl_name=$table"; + } + $query.= " AND sql NOT NULL ORDER BY name"; + $indexes = $db->queryCol($query, 'text'); + if (PEAR::isError($indexes)) { + return $indexes; + } + + $result = array(); + foreach ($indexes as $sql) { + if (preg_match("/^create unique index ([^ ]+) on /i", $sql, $tmp)) { + $index = $this->_fixIndexName($tmp[1]); + if (!empty($index)) { + $result[$index] = true; + } + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); } /** * lists table constraints diff --git a/lib/Doctrine/Table.php b/lib/Doctrine/Table.php index c659f8c58..152dcc4d0 100644 --- a/lib/Doctrine/Table.php +++ b/lib/Doctrine/Table.php @@ -1100,6 +1100,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { public function getColumnNames() { return array_keys($this->columns); } + /** * getDefinitionOf *