Skip to content

Commit

Permalink
Implement index reflection for sqlite.
Browse files Browse the repository at this point in the history
Build index/constraint reflection for Sqlite.
  • Loading branch information
markstory committed Jun 2, 2013
1 parent 13f7da9 commit 24b88c0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
31 changes: 30 additions & 1 deletion lib/Cake/Database/Schema/SqliteSchema.php
Expand Up @@ -146,19 +146,48 @@ public function convertFieldDescription(Table $table, $row, $fieldParams = []) {
* @return array An array of (sql, params) to execute.
*/
public function describeIndexSql($table) {
$sql = '';
$sql = sprintf(
'PRAGMA index_list(%s)',
$this->_driver->quoteIdentifier($table)
);
return [$sql, []];
}

/**
* Convert an index into the abstract description.
*
* Since Sqlite does not have a way to get metadata about all indexes at once,
* additional queries are done here. Sqlite constraint names are not
* stable, and the names for constraints will not match those used to create
* the table. This is a limitation in Sqlite's metadata features.
*
* @param Cake\Database\Schema\Table $table The table object to append
* an index or constraint to.
* @param array $row The row data from describeIndexSql
* @return void
*/
public function convertIndexDescription(Table $table, $row) {
$sql = sprintf(
'PRAGMA index_info(%s)',
$this->_driver->quoteIdentifier($row['name'])
);
$statement = $this->_driver->prepare($sql);
$statement->execute();
$columns = [];
foreach ($statement->fetchAll('assoc') as $column) {
$columns[] = $column['name'];
}
if ($row['unique']) {
$table->addConstraint($row['name'], [
'type' => 'unique',
'columns' => $columns
]);
} else {
$table->addIndex($row['name'], [
'type' => 'index',
'columns' => $columns
]);
}
}

/**
Expand Down
43 changes: 41 additions & 2 deletions lib/Cake/Test/TestCase/Database/Schema/SqliteSchemaTest.php
Expand Up @@ -149,10 +149,12 @@ protected function _createTables($connection) {
body TEXT,
author_id INT(11) NOT NULL,
published BOOLEAN DEFAULT 0,
created DATETIME
)
created DATETIME,
CONSTRAINT "title_idx" UNIQUE ("title", "body")
);
SQL;
$connection->execute($table);
$connection->execute('CREATE INDEX "created_idx" ON "articles" ("created")');
}

/**
Expand Down Expand Up @@ -248,6 +250,43 @@ public function testDescribeTable() {
}
}

/**
* Test describing a table with indexes
*
* @return void
*/
public function testDescribeTableIndexes() {
$connection = new Connection(Configure::read('Datasource.test'));
$this->_createTables($connection);

$schema = new SchemaCollection($connection);
$result = $schema->describe('articles');
$this->assertInstanceOf('Cake\Database\Schema\Table', $result);
$expected = [
'primary' => [
'type' => 'primary',
'columns' => ['id'],
'length' => []
],
'sqlite_autoindex_articles_1' => [
'type' => 'unique',
'columns' => ['title', 'body'],
'length' => []
]
];
$this->assertCount(2, $result->constraints());
$this->assertEquals($expected['primary'], $result->constraint('primary'));
$this->assertEquals($expected['sqlite_autoindex_articles_1'], $result->constraint('sqlite_autoindex_articles_1'));

$this->assertCount(1, $result->indexes());
$expected = [
'type' => 'index',
'columns' => ['created'],
'length' => []
];
$this->assertEquals($expected, $result->index('created_idx'));
}

/**
* Column provider for creating column sql
*
Expand Down

0 comments on commit 24b88c0

Please sign in to comment.