2017-02-15 2 views
4

В настоящее время я пишу приложение C++, где мне нужно подключиться к базе данных SQLite. Я ищу библиотеку и нашел SOCI, и я должен сказать: мне это нравится. Синтаксис потока и отображение настолько потрясающие. Но у меня есть одна проблема с этим:Запрос C++ SOCI в вектор пользовательского объекта

У меня есть класс событий, и я написал функции анализатора для него:

template<> struct type_conversion<Event> 
{ 
    typedef values base_type; 

    static void from_base(const values& v, indicator /* ind */, Event& event) 
    { 
     event.m_id = v.get<std::string>("id"); 
     event.m_title = v.get<std::string>("Title"); 
     event.m_description = v.get<std::string>("Description"); 
     event.m_date = v.get<std::tm>("Date"); 
    } 

    static void to_base(const Event& event, values& v, indicator& ind) 
    { 
     v.set("id", event.m_id); 
     v.set("Title", event.m_title); 
     v.set("Description", event.m_description); 
     v.set("Date", event.m_date); 

     ind = i_ok; 
    } 
}; 

Это прекрасно работает для запросов, как это:

sql << "SELECT * FROM Event WHERE id=5", into(event); 

Я хотел бы, чтобы выбрать большую часть событий в std::vector<Event*>, но если я попробовать это с:

std::vector<Event*> events; 
sql << "SELECT * FROM Event", into(events) 

А вот с этим я получаю следующее сообщение об ошибке компилятора:

No known convertation from 
soci::details::conversion_into_type<std::vector<Event>> into 
soci::details::into_type_base 

Разве это не возможно с SOCI или я что-то отсутствует? Я также нашел OTL в качестве библиотеки. Возможно, это хорошая альтернатива? Как я уже сказал, мне нравится путь SOCI. Возможно ли подобное с OTL?

ответ

4

SOCI не поддерживает комбинацию ORM с массовыми операциями. См. Список рассылки: ORM with std::vector not supported?.

Вместо этого, вы можете использовать набор строк и итератор-доступ:

rowset<Event> rs = (sql.prepare << "SELECT * FROM Event"); 
for (auto it = rs.cbegin(); it != rs.cend(); ++it) 
{ 
    // access event 
} 

Afair, он все еще должен быть поддержан.

+0

Большое спасибо за это! У меня есть еще два вопроса: Является ли SOCI кэшем объекты в фоновом режиме, если я снова выполняю тот же запрос? И какой правильный способ объявить «rowset» как друга, чтобы я мог сделать конструктор по умолчанию закрытым? Я попробовал 'friend class soci :: rowset ', но это не работает. – Cilenco

+0

SOCI не кэширует ничего между выдачей отдельных запросов. Тип, используемый для специализации набора строк, должен быть по умолчанию конструктивным. – mloskot

+0

Он должен быть по умолчанию конструктивным, если набор строк является другом моего класса, а конструктор является закрытым или я неправильно понимаю вас? – Cilenco