Unverified Commit 7021bdf7 authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3141 from TimoBakx/sqlite-pk-autoincrement

Allow creating PRIMARY KEY AUTOINCREMENT fields for sqlite
parents d48ea9c2 245bfb79
......@@ -307,9 +307,9 @@ class SqlitePlatform extends AbstractPlatform
*/
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
{
// sqlite autoincrement is implicit for integer PKs, but not when the field is unsigned
// sqlite autoincrement is only possible for the primary key
if ( ! empty($columnDef['autoincrement'])) {
return '';
return ' PRIMARY KEY AUTOINCREMENT';
}
return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : '';
......@@ -343,10 +343,7 @@ class SqlitePlatform extends AbstractPlatform
}
}
if (isset($options['primary']) && ! empty($options['primary'])) {
$keyColumns = array_unique(array_values($options['primary']));
$queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')';
}
$queryFields .= $this->getNonAutoincrementPrimaryKeyDefinition($columns, $options);
if (isset($options['foreignKeys'])) {
foreach ($options['foreignKeys'] as $foreignKey) {
......@@ -375,6 +372,29 @@ class SqlitePlatform extends AbstractPlatform
return $query;
}
/**
* Generate a PRIMARY KEY definition if no autoincrement value is used
*
* @param string[] $columns
* @param mixed[] $options
*/
private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $options) : string
{
if (empty($options['primary'])) {
return '';
}
$keyColumns = array_unique(array_values($options['primary']));
foreach ($keyColumns as $keyColumn) {
if (isset($columns[$keyColumn]['autoincrement']) && ! empty($columns[$keyColumn]['autoincrement'])) {
return '';
}
}
return ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
}
/**
* {@inheritDoc}
*/
......
......@@ -1489,4 +1489,32 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
self::assertFalse($tableDiff);
}
/**
* @group DBAL-2921
*/
public function testPrimaryKeyAutoIncrement()
{
$table = new Table('test_pk_auto_increment');
$table->addColumn('id', 'integer', ['autoincrement' => true]);
$table->addColumn('text', 'string');
$table->setPrimaryKey(['id']);
$this->_sm->dropAndCreateTable($table);
$this->_conn->insert('test_pk_auto_increment', ['text' => '1']);
$query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = \'1\'');
$query->execute();
$lastUsedIdBeforeDelete = (int) $query->fetchColumn();
$this->_conn->query('DELETE FROM test_pk_auto_increment');
$this->_conn->insert('test_pk_auto_increment', ['text' => '2']);
$query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = \'2\'');
$query->execute();
$lastUsedIdAfterDelete = (int) $query->fetchColumn();
$this->assertGreaterThan($lastUsedIdBeforeDelete, $lastUsedIdAfterDelete);
}
}
......@@ -232,4 +232,29 @@ SQL;
array('bigint', true, true),
);
}
/**
* @group DBAL-2921
*/
public function testPrimaryKeyNoAutoIncrement()
{
$table = new Schema\Table('test_pk_auto_increment');
$table->addColumn('id', 'integer');
$table->addColumn('text', 'text');
$table->setPrimaryKey(['id']);
$this->_sm->dropAndCreateTable($table);
$this->_conn->insert('test_pk_auto_increment', ['text' => '1']);
$this->_conn->query('DELETE FROM test_pk_auto_increment');
$this->_conn->insert('test_pk_auto_increment', ['text' => '2']);
$query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = "2"');
$query->execute();
$lastUsedIdAfterDelete = (int) $query->fetchColumn();
// with an empty table, non autoincrement rowid is always 1
$this->assertEquals(1, $lastUsedIdAfterDelete);
}
}
......@@ -19,7 +19,7 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
public function getGenerateTableSql()
{
return 'CREATE TABLE test (id INTEGER NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))';
return 'CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL)';
}
public function getGenerateTableWithMultiColumnUniqueIndexSql()
......@@ -65,7 +65,7 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
public function testIgnoresUnsignedIntegerDeclarationForAutoIncrementalIntegers()
{
self::assertSame(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true, 'unsigned' => true))
);
}
......@@ -81,11 +81,11 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$this->_platform->getTinyIntTypeDeclarationSQL(array())
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getTinyIntTypeDeclarationSQL(array('autoincrement' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getTinyIntTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true))
);
......@@ -110,15 +110,15 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$this->_platform->getSmallIntTypeDeclarationSQL(array())
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getSmallIntTypeDeclarationSQL(array('autoincrement' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getTinyIntTypeDeclarationSQL(array('autoincrement' => true, 'unsigned' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getSmallIntTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true))
);
......@@ -143,15 +143,15 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$this->_platform->getMediumIntTypeDeclarationSQL(array())
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getMediumIntTypeDeclarationSQL(array('autoincrement' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getMediumIntTypeDeclarationSQL(array('autoincrement' => true, 'unsigned' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getMediumIntTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true))
);
......@@ -172,15 +172,15 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$this->_platform->getIntegerTypeDeclarationSQL(array())
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true, 'unsigned' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getIntegerTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true))
);
......@@ -205,15 +205,15 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$this->_platform->getBigIntTypeDeclarationSQL(array())
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getBigIntTypeDeclarationSQL(array('autoincrement' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getBigIntTypeDeclarationSQL(array('autoincrement' => true, 'unsigned' => true))
);
self::assertEquals(
'INTEGER',
'INTEGER PRIMARY KEY AUTOINCREMENT',
$this->_platform->getBigIntTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true))
);
......@@ -300,7 +300,7 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
return array(
"CREATE TEMPORARY TABLE __temp__mytable AS SELECT id, bar, bloo FROM mytable",
"DROP TABLE mytable",
"CREATE TABLE mytable (id INTEGER NOT NULL, baz VARCHAR(255) DEFAULT 'def' NOT NULL, bloo BOOLEAN DEFAULT '0' NOT NULL, quota INTEGER DEFAULT NULL, PRIMARY KEY(id))",
"CREATE TABLE mytable (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, baz VARCHAR(255) DEFAULT 'def' NOT NULL, bloo BOOLEAN DEFAULT '0' NOT NULL, quota INTEGER DEFAULT NULL)",
"INSERT INTO mytable (id, baz, bloo) SELECT id, bar, bloo FROM __temp__mytable",
"DROP TABLE __temp__mytable",
"ALTER TABLE mytable RENAME TO userlist",
......@@ -318,7 +318,7 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
$createTableSQL = $this->_platform->getCreateTableSQL($table);
self::assertEquals(
'CREATE TABLE test ("like" INTEGER NOT NULL, PRIMARY KEY("like"))',
'CREATE TABLE test ("like" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)',
$createTableSQL[0]
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment