Skip to content

Commit

Permalink
No deleteing from sqlite_sequences if the table does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Nov 10, 2013
1 parent e6c77bc commit 67600df
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 5 deletions.
36 changes: 32 additions & 4 deletions Cake/Database/Schema/SqliteSchema.php
Expand Up @@ -24,6 +24,13 @@
*/
class SqliteSchema extends BaseSchema {

/**
* Whether or not this connection contains sequences
*
* @return boolean
*/
protected $_hasSequences;

/**
* Convert a column definition to the abstract types.
*
Expand Down Expand Up @@ -327,10 +334,31 @@ public function createTableSql(Table $table, $columns, $constraints, $indexes) {
*/
public function truncateTableSql(Table $table) {
$name = $table->name();
return [
sprintf('DELETE FROM sqlite_sequence WHERE name="%s"', $name),
sprintf('DELETE FROM "%s"', $name)
];
$sql = [];
if ($this->hasSequences()) {
$sql[] = sprintf('DELETE FROM sqlite_sequence WHERE name="%s"', $name);
}

$sql[] = sprintf('DELETE FROM "%s"', $name);
return $sql;
}

/**
* Returns whether there is any table in this connection to SQLite contianing
* sequences
*
* @return void
*/
public function hasSequences() {
if ($this->_hasSequences !== null) {
return $this->_hasSequences;
}
$result = $this->_driver
->prepare('SELECT 1 FROM sqlite_master WHERE name = "sqlite_sequence"');
$result->execute();
$this->_hasSequences = (bool)$result->rowCount();
$result->closeCursor();
return $this->_hasSequences;
}

}
41 changes: 40 additions & 1 deletion Cake/Test/TestCase/Database/Schema/SqliteSchemaTest.php
Expand Up @@ -674,21 +674,60 @@ public function testTruncateSql() {
$connection->expects($this->any())->method('driver')
->will($this->returnValue($driver));

$statement = $this->getMock(
'\PDOStatement',
['execute', 'rowCount', 'closeCursor', 'fetch']
);
$driver->connection()->expects($this->once())->method('prepare')
->with('SELECT 1 FROM sqlite_master WHERE name = "sqlite_sequence"')
->will($this->returnValue($statement));
$statement->expects($this->at(0))->method('fetch')
->will($this->returnValue(['1']));
$statement->expects($this->at(2))->method('fetch')
->will($this->returnValue(false));

$table = new Table('articles');
$result = $table->truncateSql($connection);
$this->assertCount(2, $result);
$this->assertEquals('DELETE FROM sqlite_sequence WHERE name="articles"', $result[0]);
$this->assertEquals('DELETE FROM "articles"', $result[1]);
}

/**
* Test truncateSql() with no sequences
*
* @return void
*/
public function testTruncateSqlNoSequences() {
$driver = $this->_getMockedDriver();
$connection = $this->getMock('Cake\Database\Connection', [], [], '', false);
$connection->expects($this->any())->method('driver')
->will($this->returnValue($driver));

$statement = $this->getMock(
'\PDOStatement',
['execute', 'rowCount', 'closeCursor', 'fetch']
);
$driver->connection()->expects($this->once())->method('prepare')
->with('SELECT 1 FROM sqlite_master WHERE name = "sqlite_sequence"')
->will($this->returnValue($statement));
$statement->expects($this->once())->method('fetch')
->will($this->returnValue(false));

$table = new Table('articles');
$result = $table->truncateSql($connection);
$this->assertCount(1, $result);
$this->assertEquals('DELETE FROM "articles"', $result[0]);
}

/**
* Get a schema instance with a mocked driver/pdo instances
*
* @return Driver
*/
protected function _getMockedDriver() {
$driver = new \Cake\Database\Driver\Sqlite();
$mock = $this->getMock('FakePdo', ['quote', 'quoteIdentifier']);
$mock = $this->getMock('FakePdo', ['quote', 'quoteIdentifier', 'prepare']);
$mock->expects($this->any())
->method('quote')
->will($this->returnCallback(function ($value) {
Expand Down

0 comments on commit 67600df

Please sign in to comment.