2017-02-15 70 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'聲明爲朋友的正確方法是什麼,這樣我可以使默認構造函數是私有的?我試過'朋友類soci :: rowset '但這不起作用。 – Cilenco

+0

SOCI在發出單獨查詢之間不會緩存任何內容。用於專門化行集的類型必須是默認可構造的。 – mloskot

+0

如果rowset是我的類的一個朋友,並且構造函數是私人的,或者我誤解了你,它應該是默認構造的? – Cilenco