1

私はSociを使用してデータベースクエリを作成します。次に、soci::rowsetをラップアラウンドするカスタム結果セットクラスが必要です。コピーコンストラクターがsociでプライベートであるという理由だけで、コードが以下のように機能するようにできません(ソースファイルではサポートされていません)。複雑なコードを使用せずに、soci :: rows(ここではRowにtypedef-ed)のリストを使用してラッパーを作成するにはどうすればよいですか?どのように進むかについてのデザインや方向性は高く評価されています

私のヘッダーファイル

typedef soci::row Row; 


class ResultSet
{
public:
    ResultSet();
    ~ResultSet();
    void Copy(soci::rowset<soci::row>& rs);

    Row GetNextRow();
    bool HasRows();

private:
    soci::rowset<soci::row> m_rows;
    soci::rowset_iterator<soci::row> m_iterator;
    bool m_isAccessed;//if first access on row is done
};

ソースファイル

ResultSet::ResultSet() {
    m_isAccessed=false;
}

ResultSet::~ResultSet() {

}

Row ResultSet::GetNextRow() {
    if(m_isAccessed) {
        m_iterator++;//increment row
        m_isAccessed=true;
    }
    return *m_iterator;
}

bool ResultSet::HasRows() {
    return m_iterator!=m_rows.end();//it have not reached the end yet;
}

void ResultSet::Copy(soci::rowset<soci::row>& rs) {
    m_rows = rs;
    m_iterator = rs.begin();//put it at row 1
}

これが、接続のExecuteQuery関数での使用方法です。m_sessionはsoci::sessionです

void ConnectionMgr::ExecuteQuery(wxString& sql, ResultSet& rs) {
    try { 
        soci::rowset<soci::row> rsInternal = m_session.prepare<<sql.ToStdString();
        rs.Copy(rsInternal); 
    }
    catch (std::exception const& e) {
        m_error = wxString::Format(wxT("SqlQuery close error:%s\n"), e.what());
    }
}

後でクラスをどのように使用したいかの例

wxString sql = wxT("-- a query\n SHOW DATABASES;"); 
                ResultSet rs;
                m_conn->ExecuteQuery(sql, rs);
                while(rs.HasRows())
                {
                    wxString name = wxString(rs.GetNextRow().get<std::string>(0));
                    //work with name here
                }
4

1 に答える 1

0

SOCIには多くの制限があり、ソースを変更せずにそのようなタスクを実行することは不可能であるように思われます。つまり、変更を自分で維持する必要があります(開発者がパッチを受け入れない限り)。

私はwxWidgetsを使用しているので、databaselayerをwxDatabaseとして復活させ、それを使用して維持することにしました。

于 2012-11-30T07:50:33.737 に答える