Search code examples
c++wt

QueryModel in WTableView: Please, an example of how to add a row and fill it with new record just created


I've made a table:

class TableTag
{
public:
    std::string name;
    //Wt::Dbo::collection< Wt::Dbo::ptr<TablePost> > tablePosts;

    TableTag();
    ~TableTag();
    static void initTableRecords(Wt::Dbo::Session &_session);

    template<class Action>
    void persist(Action &_action)
    {
        Wt::Dbo::field(_action, name, "Name");
    }
};
typedef Wt::Dbo::collection< Wt::Dbo::ptr<TableTag> > TableTags;

I create a Model and add it to a WTableView:

qModelTags_ = new Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> >();
qModelTags_->setQuery(ddbbSession_->find<TableTag>());
qModelTags_->addAllFieldsAsColumns();

//WtableView
ctrGridTags_ = new WTableView(this);
ctrGridTags_->setModel(qModelTags_); //qmTags1
ctrGridTags_->setSelectionMode(Wt::SelectionMode::SingleSelection);
root()->addWidget(ctrGridTags_);

This works OK. Now, I want to insert a record in the table:

        {
        Wt::Dbo::Transaction transaction(*ddbbSession_);

        Wt::Dbo::ptr<TableTag> tag = ddbbSession_->add(new TableTag());
        tag.modify()->name = "Example";            
        }

and refresh the view:

        qModelTags_->reload();

This works, but I feel that if I have a table with 100.000 records and 100 fields, It's not acceptable to reload all records and fields in order to show a only one new record. I think I should use something like:

        int rowNo = qModelTags_->rowCount();
        qModelTags_->insertRow(rowNo);
        qModelTags_->setItemData(...)
        qModelTags_->setData(...) 

But I can't figure how. I've googled, I've looked into examples, forums... but I found no example! Can anyone help me with a simple example? Thanks in advance...


Solution

  • Koen Deforche (the Wt framework's creator) replied me in the Wt forum, and pointed me to the right path (thanks, Koen!!). I think I should share the answer for all you, so here I go:

    I infer that, given a QueryModel associated to a WTableView, there are two ways to insert records and refresh the table and underlying query:

    1.- Insert records directly in database and reload the entire QueryModel:

    {
    //Insert one or more records...
    Wt::Dbo::Transaction transaction(*ddbbSession_);
    
    Wt::Dbo::ptr<TableTag> tag = ddbbSession_->add(new TableTag());
    tag.modify()->name = "Example";            
    }
    qModelTags_->reload();
    

    2.- Insert records indirectly one by one via the QueryModel, wich will autorefresh the WTableView:

    int rowNo = qModelTags_->rowCount();
    qModelTags_->insertRow(rowNo);
    qModelTags_->setData(rowNo, 1, newTagName.narrow());
    ctrGridTags_->select(qModelTags_->index(rowNo, 0));