Feature #4008 ยป 0001-Support-specialized-orderBy-clause-in-QueryModel.patch
src/Wt/Dbo/QueryModel | ||
---|---|---|
*
|
||
* This sorts the model by changing the query using
|
||
* Query<BindStrategy>::orderBy().
|
||
*
|
||
* \sa createOrderBy()
|
||
*/
|
||
virtual void sort(int column, SortOrder order = AscendingOrder);
|
||
/*! \brief Create specialized orderBy clause for sort
|
||
*
|
||
* The sort() method calls createOrderBy() to format a SQL
|
||
* clause for use in Query<BindStrategy>::orderBy().
|
||
* The default is to return a string that will sort on
|
||
* a single column in the specified order.
|
||
*
|
||
* Customize this method if you need a more complex orderBy
|
||
* clause, e.g. to break ties consistently.
|
||
*
|
||
* \sa sort()
|
||
*/
|
||
virtual std::string createOrderBy(int column, SortOrder order);
|
||
/*! \brief Inserts one or more rows.
|
||
*
|
||
* Row insertions are only supported at the end (\p row ==
|
src/Wt/Dbo/QueryModel_impl.h | ||
---|---|---|
invalidateData();
|
||
query_.orderBy(fields_[columns_[column].fieldIdx_].sql() + " "
|
||
+ (order == AscendingOrder ? "asc" : "desc"));
|
||
query_.orderBy(createOrderBy(column, order));
|
||
cachedRowCount_ = rc;
|
||
dataReloaded();
|
||
}
|
||
template <class Result>
|
||
std::string QueryModel<Result>::createOrderBy(int column, SortOrder order)
|
||
{
|
||
return fieldInfo(column).sql() + " "
|
||
+ (order == AscendingOrder ? "asc" : "desc");
|
||
}
|
||
template <class Result>
|
||
Result QueryModel<Result>::stableResultRow(int row) const
|
||
{
|
||
StableResultIdMap::const_iterator i = stableIds_.find(row);
|
test/dbo/DboTest.C | ||
---|---|---|
class C;
|
||
class D;
|
||
class E;
|
||
class F;
|
||
bool fractionalSeconds = true;
|
||
... | ... | |
session_->mapClass<C>(SCHEMA "table_c");
|
||
session_->mapClass<D>(SCHEMA "table_d");
|
||
session_->mapClass<E>(SCHEMA "table_e");
|
||
session_->mapClass<F>(SCHEMA "table_f");
|
||
try {
|
||
session_->dropTables();
|
||
... | ... | |
}
|
||
};
|
||
class F {
|
||
public:
|
||
std::string firstName;
|
||
std::string lastName;
|
||
std::string gender;
|
||
F() { }
|
||
F(const std::string& aFirstName, const std::string& aLastName, const std::string& aGender)
|
||
: firstName(aFirstName), lastName(aLastName), gender(aGender)
|
||
{ }
|
||
template <class Action>
|
||
void persist(Action& a)
|
||
{
|
||
dbo::field(a, firstName, "first_name", 1000);
|
||
dbo::field(a, lastName, "last_name", 1000);
|
||
dbo::field(a, gender, "gender", 1000);
|
||
}
|
||
};
|
||
BOOST_AUTO_TEST_CASE( dbo_test1 )
|
||
{
|
||
DboFixture f;
|
||
... | ... | |
BOOST_REQUIRE(dc.get<1>()->name == "c1");
|
||
}
|
||
}
|
||
BOOST_AUTO_TEST_CASE( dbo_test25 )
|
||
{
|
||
DboFixture f;
|
||
dbo::Session *session_ = f.session_;
|
||
{
|
||
dbo::Transaction t(*session_);
|
||
dbo::ptr<F> e1 = session_->add(new F("Alice", "Kramden", "Female"));
|
||
dbo::ptr<F> e2 = session_->add(new F("Ralph", "Kramden", "Male"));
|
||
dbo::ptr<F> e3 = session_->add(new F("Trixie", "Norton", "Female"));
|
||
dbo::ptr<F> e4 = session_->add(new F("Ed", "Norton", "Male"));
|
||
t.commit();
|
||
}
|
||
{
|
||
dbo::Query< dbo::ptr<F> > query = session_->find<F>().orderBy("id");
|
||
dbo::QueryModel< dbo::ptr<F> > *model
|
||
= new dbo::QueryModel< dbo::ptr<F> >();
|
||
model->setQuery(query);
|
||
model->addAllFieldsAsColumns();
|
||
BOOST_REQUIRE(model->columnCount() == 5);
|
||
BOOST_REQUIRE(model->rowCount() == 4);
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(0)) == "id");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(1)) == "version");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(2)) == "first_name");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(3)) == "last_name");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(4)) == "gender");
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Trixie");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Ed");
|
||
// sort on first name
|
||
model->sort(2, Wt::SortOrder::AscendingOrder);
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Ed");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Trixie");
|
||
delete model;
|
||
}
|
||
{
|
||
class custom_sort_model : public dbo::QueryModel< dbo::ptr<F> > {
|
||
public:
|
||
custom_sort_model() : dbo::QueryModel< dbo::ptr<F> >() { }
|
||
virtual std::string createOrderBy(int column, Wt::SortOrder order)
|
||
{
|
||
std::string dir = (order == Wt::SortOrder::AscendingOrder ? "asc" : "desc");
|
||
return fieldInfo(column).name() + " " + dir +
|
||
((column != 3) ? ", last_name" : "") +
|
||
((column != 2) ? ", first_name" : "");
|
||
}
|
||
};
|
||
dbo::Query< dbo::ptr<F> > query = session_->find<F>().orderBy("id");
|
||
custom_sort_model *model = new custom_sort_model();
|
||
model->setQuery(query);
|
||
model->addAllFieldsAsColumns();
|
||
BOOST_REQUIRE(model->columnCount() == 5);
|
||
BOOST_REQUIRE(model->rowCount() == 4);
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(0)) == "id");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(1)) == "version");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(2)) == "first_name");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(3)) == "last_name");
|
||
BOOST_REQUIRE(Wt::asString(model->headerData(4)) == "gender");
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Trixie");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Ed");
|
||
// sort on last name ascending, then first name ascending
|
||
model->sort(3, Wt::SortOrder::AscendingOrder);
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Ed");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Trixie");
|
||
// sort on last name descending, then first name ascending
|
||
model->sort(3, Wt::SortOrder::DescendingOrder);
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Ed");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Trixie");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Ralph");
|
||
// sort on first name, then last name ascending
|
||
model->sort(2, Wt::SortOrder::AscendingOrder);
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Ed");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Trixie");
|
||
// sort on gender, then last name, then first name
|
||
model->sort(4, Wt::SortOrder::AscendingOrder);
|
||
BOOST_REQUIRE(Wt::asString(model->data(0, 2)) == "Alice");
|
||
BOOST_REQUIRE(Wt::asString(model->data(1, 2)) == "Trixie");
|
||
BOOST_REQUIRE(Wt::asString(model->data(2, 2)) == "Ralph");
|
||
BOOST_REQUIRE(Wt::asString(model->data(3, 2)) == "Ed");
|
||
delete model;
|
||
}
|
||
}
|