I'm working on the contributed Login History module which has an existing table that does not have a primary key. I'd like to add a primary key to the table, but am struggle with the db_add_field
syntax for upgrades. The existing table is:
/**
* Implements hook_schema().
*/
function login_history_schema() {
$schema['login_history'] = array(
'fields' => array(
'uid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'uid of user.',
),
'login' => array(
'type' => 'int',
'not null' => TRUE,
'description' => "Timestamp for user's login.",
),
'hostname' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => "The user's host name.",
),
'one_time' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Indicates whether the login was from a one-time login link (e.g. password reset).',
),
'user_agent' => array(
'type' => 'varchar',
'length' => 256,
'not null' => TRUE,
'default' => '',
'description' => 'User agent (i.e. browser) of the device used during the login.',
),
),
'indexes' => array(
'login_history_uid' => array('uid'),
'login_history_onetime' => array('one_time'),
'login_history_uid_host' => array('uid', 'hostname'),
),
);
return $schema;
}
And what I think should work to add a primary key is a hook_update like this:
/**
* Add device_id and login_id columns.
*/
function login_history_update_7106() {
if (!db_field_exists('login_history', 'login_id')) {
db_add_field(
'login_history',
'login_id',
array(
'description' => 'The primary identifier for a login.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
array('primary key' => array('login_id')));
}
}
However, that results in this error:
SQLSTATE[42000]: Syntax error or access violation: 1171 All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead [error]
I've tried:
- Reading and re-reading the docs for
db_add_field
anddb_change_field
- Using
db_add_field
to add an empty int field and then usingdb_change_field
to make it a serial primary key. - Using
db_add_field
without the 4th parameter that sets the new primary keys and then trying to usedb_add_primary_key('login_history', array('login_id'))
but that gives an error before the field is even added saying that auto_increment fields have to be part of a unique key.
I've grepped core and some contrib looking for instances of adding an auto increment primary key and can't find any for Drupal 7.