Skip to content

Commit

Permalink
Fix/add index generation to Sqlite.
Browse files Browse the repository at this point in the history
Previously Sqlite could not create standard indexes for optimizing
queries. Now it can create basic unsorted indexs like other databases.
  • Loading branch information
markstory committed May 20, 2013
1 parent d5ceb63 commit b374340
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 14 deletions.
37 changes: 27 additions & 10 deletions lib/Cake/Database/Schema/SqliteSchema.php
Expand Up @@ -132,8 +132,8 @@ public function convertFieldDescription(Table $table, $row, $fieldParams = []) {
}
$table->addColumn($row['name'], $field);
if ($row['pk'] == true) {
$table->addIndex('primary', [
'type' => Table::INDEX_PRIMARY,
$table->addConstraint('primary', [
'type' => Table::CONSTRAINT_PRIMARY,
'columns' => [$row['name']]
]);
}
Expand Down Expand Up @@ -207,18 +207,18 @@ public function columnSql(Table $table, $name) {
* @return string SQL fragment.
*/
public function constraintSql(Table $table, $name) {
$data = $table->index($name);
$data = $table->constraint($name);
if (
count($data['columns']) === 1 &&
$table->column($data['columns'][0])['type'] === 'integer'
) {
return '';
}
$out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name);
if ($data['type'] === Table::INDEX_PRIMARY) {
if ($data['type'] === Table::CONSTRAINT_PRIMARY) {
$out .= ' PRIMARY KEY';
}
if ($data['type'] === Table::INDEX_UNIQUE) {
if ($data['type'] === Table::CONSTRAINT_UNIQUE) {
$out .= ' UNIQUE';
}
$columns = array_map(
Expand All @@ -236,18 +236,35 @@ public function constraintSql(Table $table, $name) {
* @return string SQL fragment.
*/
public function indexSql(Table $table, $name) {
return '';
$data = $table->index($name);
$columns = array_map(
[$this->_driver, 'quoteIdentifier'],
$data['columns']
);
return sprintf('CREATE INDEX %s ON %s (%s)',
$this->_driver->quoteIdentifier($name),
$this->_driver->quoteIdentifier($table->name()),
implode(', ', $columns)
);
}

/**
* Generate the SQL to create a table.
*
* @param string $table The name of the table.
* @param array $lines The lines (columns + indexes) to go inside the table.
* @return string A complete CREATE TABLE statement
* @param array $columns The columns to go inside the table.
* @param array $constraints The constraints for the table.
* @param array $indexes The indexes for the table.
* @return array A complete CREATE TABLE statement(s)S
*/
public function createTableSql($table, $lines) {
public function createTableSql($table, $columns, $constraints, $indexes) {
$lines = array_merge($columns, $constraints);
$content = implode(",\n", array_filter($lines));
return sprintf("CREATE TABLE \"%s\" (\n%s\n);", $table, $content);
$table = sprintf("CREATE TABLE \"%s\" (\n%s\n);", $table, $content);
$out = [$table];
foreach ($indexes as $index) {
$out[] = $index . ";";
}
return $out;
}
}
51 changes: 47 additions & 4 deletions lib/Cake/Test/TestCase/Database/Schema/SqliteSchemaTest.php
Expand Up @@ -390,7 +390,7 @@ public function testColumnSqlPrimaryKey() {
'type' => 'integer',
'null' => false
])
->addIndex('primary', [
->addConstraint('primary', [
'type' => 'primary',
'columns' => ['id']
]);
Expand Down Expand Up @@ -435,11 +435,45 @@ public function testConstraintSql($name, $data, $expected) {
'length' => 255
])->addColumn('author_id', [
'type' => 'integer',
])->addIndex($name, $data);
])->addConstraint($name, $data);

$this->assertEquals($expected, $schema->constraintSql($table, $name));
}

/**
* Provide data for testing indexSql
*
* @return array
*/
public static function indexSqlProvider() {
return [
[
'author_idx',
['type' => 'index', 'columns' => ['title', 'author_id']],
'CREATE INDEX "author_idx" ON "articles" ("title", "author_id")'
],
];
}

/**
* Test the indexSql method.
*
* @dataProvider indexSqlProvider
*/
public function testIndexSql($name, $data, $expected) {
$driver = $this->_getMockedDriver();
$schema = new SqliteSchema($driver);

$table = (new Table('articles'))->addColumn('title', [
'type' => 'string',
'length' => 255
])->addColumn('author_id', [
'type' => 'integer',
])->addIndex($name, $data);

$this->assertEquals($expected, $schema->indexSql($table, $name));
}

/**
* Integration test for converting a Schema\Table into MySQL table creates.
*
Expand All @@ -461,9 +495,13 @@ public function testCreateTableSql() {
])
->addColumn('body', ['type' => 'text'])
->addColumn('created', 'datetime')
->addIndex('primary', [
->addConstraint('primary', [
'type' => 'primary',
'columns' => ['id']
])
->addIndex('title_idx', [
'type' => 'index',
'columns' => ['title']
]);

$expected = <<<SQL
Expand All @@ -475,7 +513,12 @@ public function testCreateTableSql() {
);
SQL;
$result = $table->createTableSql($connection);
$this->assertEquals($expected, $result);
$this->assertCount(2, $result);
$this->assertEquals($expected, $result[0]);
$this->assertEquals(
'CREATE INDEX "title_idx" ON "articles" ("title");',
$result[1]
);
}

/**
Expand Down

0 comments on commit b374340

Please sign in to comment.