Я использую MySQl с включенным sql-режимом NO_AUTO_VALUE_ON_ZERO, что означает, что невозможно использовать 0 в операторах INSERT для столбца PK, чтобы указать MySQL, что ему следует автоматически назначать значение для PK.
У меня есть постоянный объект следующего определения:
#pragma db object
struct person
{
#pragma db id auto
uint64_t id_ = 0;
std::string first_name_;
std::string last_name_;
};
И таблица:
CREATE TABLE `person` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(50) NOT NULL,
`last_name` VARCHAR(50) NOT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 collate=utf8_unicode_ci;
Я предполагаю, что спецификатор ‘id auto’ должен генерировать следующие sql в классах mapper:
INSERT INTO person (first_name, last_name) VALUES ("John", "Dohn");
но реальный sql это:
INSERT INTO person (id, first_name, last_name) VALUES (0, "John", "Dohn");
что приводит к вставке строки со значением PK, равным нулю, и приводит к дублированию ошибок PK вместо вставки строки с автоинкрементным идентификатором.
Есть ли способ заставить odb compliter генерировать правильный SQL-код, потому что я не хочу отключать NO_AUTO_VALUE_ON_ZERO?
Я обнаружил, что единственным возможным способом достижения правильного поведения является использование odb :: nullable:
#pragma db object
struct person
{
#pragma db id auto
odb::nullable<uint64_t> id_;
std::string first_name_;
std::string last_name_;
};
При таком подходе odb будет генерировать следующий запрос, если id_ оставлен неинициализированным:
INSERT INTO person (id, first_name, last_name) VALUES (NULL, "John", "Dohn");
что именно то, что мне нужно.
Других решений пока нет …