Adding index() to dbo_postgres. Tests added for index introspection. Also fixes object to string conversions when working with database expressions. Fixes #5867

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7922 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
mark_story 2008-12-15 02:25:55 +00:00
parent a601129d46
commit 48c65c4092
2 changed files with 74 additions and 1 deletions

View file

@ -382,7 +382,10 @@ class DboPostgres extends DboSource {
* @return string SQL field
*/
function name($data) {
return parent::name(str_replace('"__"', '__', $data));
if (is_string($data)) {
$data = str_replace('"__"', '__', $data);
}
return parent::name($data);
}
/**
* Generates the fields list of an SQL query.
@ -423,6 +426,44 @@ class DboPostgres extends DboSource {
}
return $fields;
}
/**
* Returns an array of the indexes in given datasource name.
*
* @param string $model Name of model to inspect
* @return array Fields in table. Keys are column and unique
*/
function index($model) {
$index = array();
$table = $this->fullTableName($model, false);
if ($table) {
$indexes = $this->query("SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) as statement, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
WHERE c.oid = (
SELECT c.oid
FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ '^(" . $table . ")$'
AND pg_catalog.pg_table_is_visible(c.oid)
AND n.nspname ~ '^(" . $this->config['schema'] . ")$'
)
AND c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname");
foreach ($indexes as $i => $info) {
$key = array_pop($info);
if ($key['indisprimary']) {
$key['relname'] = 'PRIMARY';
}
$col = array();
preg_match('/\(([^\)]+)\)/', $key['statement'], $indexColumns);
$parsedColumn = $indexColumns[1];
if (strpos($indexColumns[1], ',') !== false) {
$parsedColumn = explode(', ', $indexColumns[1]);
}
$index[$key['relname']]['unique'] = $key['indisunique'];
$index[$key['relname']]['column'] = $parsedColumn;
}
}
return $index;
}
/**
* Returns a limit statement in the correct format for the particular database.
*

View file

@ -479,5 +479,37 @@ class DboPostgresTest extends CakeTestCase {
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
}
/**
* Test index generation from table info.
*
* @return void
**/
function testIndexGeneration() {
$name = $this->db->fullTableName('index_test', false);
$this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
$this->db->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
$this->db->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => 1),
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
'char_index' => array('column' => 'small_char', 'unique' => 1),
);
$result = $this->db->index($name);
$this->assertEqual($expected, $result);
$this->db->query('DROP TABLE ' . $name);
$name = $this->db->fullTableName('index_test_2', false);
$this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
$this->db->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => 1),
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
);
$result = $this->db->index($name);
$this->assertEqual($expected, $result);
$this->db->query('DROP TABLE ' . $name);
}
}
?>